@bitfab/sdk 0.23.2 → 0.24.0
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/{chunk-EQI6ZJC3.js → chunk-26MUT4IP.js} +57 -2
- package/dist/chunk-26MUT4IP.js.map +1 -0
- package/dist/{chunk-PP5K6RIU.js → chunk-S3PN26RH.js} +322 -206
- package/dist/chunk-S3PN26RH.js.map +1 -0
- package/dist/index.cjs +393 -205
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -8
- package/dist/index.d.ts +24 -8
- package/dist/index.js +2 -2
- package/dist/node.cjs +393 -205
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +0 -1
- package/dist/node.d.ts +0 -1
- package/dist/node.js +2 -2
- package/dist/{replay-V6RPJYXZ.js → replay-CQIU2ITL.js} +4 -3
- package/dist/replay-CQIU2ITL.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-EQI6ZJC3.js.map +0 -1
- package/dist/chunk-PP5K6RIU.js.map +0 -1
- package/dist/replay-V6RPJYXZ.js.map +0 -1
|
@@ -5,16 +5,26 @@ import {
|
|
|
5
5
|
deserializeValue,
|
|
6
6
|
getReplayContext,
|
|
7
7
|
isAsyncStorageInitDone,
|
|
8
|
+
randomUuid,
|
|
8
9
|
serializeValue,
|
|
9
|
-
toJsonSafe
|
|
10
|
-
|
|
10
|
+
toJsonSafe,
|
|
11
|
+
warnOnce
|
|
12
|
+
} from "./chunk-26MUT4IP.js";
|
|
11
13
|
|
|
12
14
|
// src/version.generated.ts
|
|
13
|
-
var __version__ = "0.
|
|
15
|
+
var __version__ = "0.24.0";
|
|
14
16
|
|
|
15
17
|
// src/constants.ts
|
|
16
18
|
var DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
17
19
|
|
|
20
|
+
// src/unrefTimer.ts
|
|
21
|
+
function unrefTimer(timer) {
|
|
22
|
+
const handle = timer;
|
|
23
|
+
if (typeof handle.unref === "function") {
|
|
24
|
+
handle.unref();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
18
28
|
// src/http.ts
|
|
19
29
|
function serializePayloadBody(payload) {
|
|
20
30
|
try {
|
|
@@ -60,11 +70,20 @@ function serializePayloadBody(payload) {
|
|
|
60
70
|
result = `<unserializable: ${className}>`;
|
|
61
71
|
}
|
|
62
72
|
} else {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
73
|
+
try {
|
|
74
|
+
const out = {};
|
|
75
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
76
|
+
out[k] = sanitize(v, seen);
|
|
77
|
+
}
|
|
78
|
+
result = out;
|
|
79
|
+
} catch {
|
|
80
|
+
warnOnce(
|
|
81
|
+
"payload:field-getter-threw",
|
|
82
|
+
"a value with a throwing getter/proxy could not be serialized into a span payload; it was replaced with a placeholder. The span still ships with its other fields intact."
|
|
83
|
+
);
|
|
84
|
+
dropped.push(className);
|
|
85
|
+
result = `<unserializable: ${className}>`;
|
|
66
86
|
}
|
|
67
|
-
result = out;
|
|
68
87
|
}
|
|
69
88
|
seen.delete(obj);
|
|
70
89
|
return result;
|
|
@@ -109,10 +128,20 @@ async function flushTraces(timeoutMs = 5e3) {
|
|
|
109
128
|
if (pendingTracePromises.size === 0) {
|
|
110
129
|
return;
|
|
111
130
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
131
|
+
let timer;
|
|
132
|
+
try {
|
|
133
|
+
await Promise.race([
|
|
134
|
+
Promise.allSettled(Array.from(pendingTracePromises)),
|
|
135
|
+
new Promise((resolve) => {
|
|
136
|
+
timer = setTimeout(resolve, timeoutMs);
|
|
137
|
+
unrefTimer(timer);
|
|
138
|
+
})
|
|
139
|
+
]);
|
|
140
|
+
} finally {
|
|
141
|
+
if (timer) {
|
|
142
|
+
clearTimeout(timer);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
116
145
|
}
|
|
117
146
|
if (typeof process !== "undefined" && process.versions != null && process.versions.node != null) {
|
|
118
147
|
let isFlushing = false;
|
|
@@ -508,7 +537,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
508
537
|
if (this.activeContext) {
|
|
509
538
|
this.traceId = this.activeContext.traceId;
|
|
510
539
|
} else {
|
|
511
|
-
this.traceId =
|
|
540
|
+
this.traceId = randomUuid();
|
|
512
541
|
}
|
|
513
542
|
this.traceStartedAt = nowIso();
|
|
514
543
|
return this.traceId;
|
|
@@ -533,7 +562,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
533
562
|
if (this.activeContext !== null) {
|
|
534
563
|
return;
|
|
535
564
|
}
|
|
536
|
-
const spanId =
|
|
565
|
+
const spanId = randomUuid();
|
|
537
566
|
this.startSpan(spanId, this.traceFunctionKey, "agent", this.rootInput, null);
|
|
538
567
|
this.rootSpanId = spanId;
|
|
539
568
|
}
|
|
@@ -647,7 +676,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
647
676
|
// ── hook callbacks ───────────────────────────────────────────
|
|
648
677
|
async preToolUseHook(inputData, toolUseId, _context) {
|
|
649
678
|
try {
|
|
650
|
-
const sid = inputData.tool_use_id ?? toolUseId ??
|
|
679
|
+
const sid = inputData.tool_use_id ?? toolUseId ?? randomUuid();
|
|
651
680
|
const toolName = inputData.tool_name ?? "tool";
|
|
652
681
|
const toolInput = inputData.tool_input ?? {};
|
|
653
682
|
const agentId = inputData.agent_id;
|
|
@@ -677,10 +706,10 @@ var BitfabClaudeAgentHandler = class {
|
|
|
677
706
|
}
|
|
678
707
|
async subagentStartHook(inputData, _toolUseId, _context) {
|
|
679
708
|
try {
|
|
680
|
-
const agentId = inputData.agent_id ??
|
|
709
|
+
const agentId = inputData.agent_id ?? randomUuid();
|
|
681
710
|
const agentType = inputData.agent_type ?? "subagent";
|
|
682
711
|
const parentId = this.getParentId();
|
|
683
|
-
const spanId =
|
|
712
|
+
const spanId = randomUuid();
|
|
684
713
|
this.activeSubagentSpans.set(agentId, spanId);
|
|
685
714
|
this.startSpan(
|
|
686
715
|
spanId,
|
|
@@ -821,7 +850,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
821
850
|
this.flushLlmTurn();
|
|
822
851
|
this.conversationHistory.push(...this.pendingMessages);
|
|
823
852
|
this.pendingMessages = [];
|
|
824
|
-
this.currentLlmSpanId =
|
|
853
|
+
this.currentLlmSpanId = randomUuid();
|
|
825
854
|
this.currentLlmMessageId = messageId ?? null;
|
|
826
855
|
this.currentLlmContent = [];
|
|
827
856
|
this.currentLlmModel = inner.model ?? null;
|
|
@@ -946,6 +975,16 @@ var BitfabClaudeAgentHandler = class {
|
|
|
946
975
|
}
|
|
947
976
|
};
|
|
948
977
|
|
|
978
|
+
// src/optionalPeer.ts
|
|
979
|
+
function importOptionalPeer(specifierParts) {
|
|
980
|
+
const specifier = specifierParts.join("/");
|
|
981
|
+
return import(
|
|
982
|
+
/* webpackIgnore: true */
|
|
983
|
+
/* @vite-ignore */
|
|
984
|
+
specifier
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
|
|
949
988
|
// src/baml.ts
|
|
950
989
|
var cachedBaml = null;
|
|
951
990
|
async function loadBaml() {
|
|
@@ -953,7 +992,7 @@ async function loadBaml() {
|
|
|
953
992
|
return cachedBaml;
|
|
954
993
|
}
|
|
955
994
|
try {
|
|
956
|
-
cachedBaml = await
|
|
995
|
+
cachedBaml = await importOptionalPeer(["@boundaryml", "baml"]);
|
|
957
996
|
return cachedBaml;
|
|
958
997
|
} catch {
|
|
959
998
|
throw new Error(
|
|
@@ -1498,7 +1537,7 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
1498
1537
|
} else {
|
|
1499
1538
|
const activeContext = this.getActiveSpanContext?.() ?? null;
|
|
1500
1539
|
invocation = {
|
|
1501
|
-
traceId: activeContext ? activeContext.traceId :
|
|
1540
|
+
traceId: activeContext ? activeContext.traceId : randomUuid(),
|
|
1502
1541
|
activeContext,
|
|
1503
1542
|
rootRunId: runId
|
|
1504
1543
|
};
|
|
@@ -1793,8 +1832,25 @@ var BitfabOpenAIAgentHandler = class {
|
|
|
1793
1832
|
this.withSpanFn = config.withSpan;
|
|
1794
1833
|
this.getActiveSpanContext = config.getActiveSpanContext;
|
|
1795
1834
|
}
|
|
1835
|
+
/**
|
|
1836
|
+
* Drop-in replacement for the OpenAI Agents SDK's `run()` that records a
|
|
1837
|
+
* replayable root `agent` span.
|
|
1838
|
+
*
|
|
1839
|
+
* The `input` is captured as the root span's input (as a single positional
|
|
1840
|
+
* argument, so `replay(key, fn)` re-feeds it), and the run's `finalOutput`
|
|
1841
|
+
* is recorded as the root output. For streaming runs (`{ stream: true }`),
|
|
1842
|
+
* the result is handed back immediately and the final output is recorded
|
|
1843
|
+
* once the stream completes — first-byte latency is untouched.
|
|
1844
|
+
*
|
|
1845
|
+
* The process-wide tracing processor (`getOpenAiTracingProcessor`) must still
|
|
1846
|
+
* be registered: it captures the LLM/tool/handoff spans that nest beneath
|
|
1847
|
+
* this root.
|
|
1848
|
+
*/
|
|
1796
1849
|
async wrapRun(agent, input, options) {
|
|
1797
|
-
const { run } = await
|
|
1850
|
+
const { run } = await importOptionalPeer([
|
|
1851
|
+
"@openai",
|
|
1852
|
+
"agents"
|
|
1853
|
+
]);
|
|
1798
1854
|
if (this.getActiveSpanContext?.() != null) {
|
|
1799
1855
|
return run(
|
|
1800
1856
|
agent,
|
|
@@ -2338,7 +2394,10 @@ async function loadCollectorClass() {
|
|
|
2338
2394
|
return cachedCollectorClass;
|
|
2339
2395
|
}
|
|
2340
2396
|
try {
|
|
2341
|
-
const baml = await
|
|
2397
|
+
const baml = await importOptionalPeer([
|
|
2398
|
+
"@boundaryml",
|
|
2399
|
+
"baml"
|
|
2400
|
+
]);
|
|
2342
2401
|
cachedCollectorClass = baml.Collector;
|
|
2343
2402
|
return cachedCollectorClass;
|
|
2344
2403
|
} catch {
|
|
@@ -2595,7 +2654,20 @@ var Bitfab = class {
|
|
|
2595
2654
|
functionVersion.providers,
|
|
2596
2655
|
this.envVars
|
|
2597
2656
|
);
|
|
2598
|
-
|
|
2657
|
+
let resultStr;
|
|
2658
|
+
if (typeof executionResult.result === "string") {
|
|
2659
|
+
resultStr = executionResult.result;
|
|
2660
|
+
} else {
|
|
2661
|
+
try {
|
|
2662
|
+
resultStr = JSON.stringify(executionResult.result) ?? String(executionResult.result);
|
|
2663
|
+
} catch {
|
|
2664
|
+
warnOnce(
|
|
2665
|
+
"call-result-serialize",
|
|
2666
|
+
"a local execution result could not be JSON-serialized; storing its String() form instead. The call still returns its real value."
|
|
2667
|
+
);
|
|
2668
|
+
resultStr = String(executionResult.result);
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2599
2671
|
this.httpClient.sendInternalTrace(functionVersion.id, {
|
|
2600
2672
|
result: resultStr,
|
|
2601
2673
|
source: "typescript-sdk",
|
|
@@ -2844,11 +2916,26 @@ var Bitfab = class {
|
|
|
2844
2916
|
return await bamlClient[methodName](...args);
|
|
2845
2917
|
}
|
|
2846
2918
|
const collector = new CollectorClass("bitfab-baml-tracing");
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
trackedClient
|
|
2851
|
-
|
|
2919
|
+
let trackedClient;
|
|
2920
|
+
let trackedMethod;
|
|
2921
|
+
try {
|
|
2922
|
+
trackedClient = bamlClient.withOptions({ collector });
|
|
2923
|
+
const method2 = trackedClient[methodName];
|
|
2924
|
+
if (typeof method2 !== "function") {
|
|
2925
|
+
throw new BitfabError(
|
|
2926
|
+
"bamlClient.withOptions did not return the wrapped method"
|
|
2927
|
+
);
|
|
2928
|
+
}
|
|
2929
|
+
trackedMethod = method2;
|
|
2930
|
+
} catch {
|
|
2931
|
+
warnOnce(
|
|
2932
|
+
`wrapBAML-setup:${methodName}`,
|
|
2933
|
+
`BAML tracing setup failed for "${methodName}" (incompatible bamlClient or BAML version); calling it untraced. The call still runs; no span is recorded.`
|
|
2934
|
+
);
|
|
2935
|
+
wrappedFn.collector = null;
|
|
2936
|
+
return await bamlClient[methodName](...args);
|
|
2937
|
+
}
|
|
2938
|
+
const result = await trackedMethod.bind(trackedClient)(...args);
|
|
2852
2939
|
wrappedFn.collector = collector;
|
|
2853
2940
|
try {
|
|
2854
2941
|
const prompt = extractPromptFromCollector(collector);
|
|
@@ -2924,200 +3011,229 @@ var Bitfab = class {
|
|
|
2924
3011
|
() => wrappedFn.apply(this, args)
|
|
2925
3012
|
);
|
|
2926
3013
|
}
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
const
|
|
2941
|
-
|
|
3014
|
+
let newStack;
|
|
3015
|
+
let executeWithContext;
|
|
3016
|
+
let registeredTraceId;
|
|
3017
|
+
try {
|
|
3018
|
+
const currentStack = getSpanStack();
|
|
3019
|
+
const parentContext = currentStack[currentStack.length - 1];
|
|
3020
|
+
const replayCtxForTraceId = parentContext ? null : getReplayContext();
|
|
3021
|
+
const traceId = parentContext?.traceId ?? replayCtxForTraceId?.traceId ?? randomUuid();
|
|
3022
|
+
const spanId = randomUuid();
|
|
3023
|
+
const parentSpanId = parentContext?.spanId ?? null;
|
|
3024
|
+
const isRootSpan = parentSpanId === null;
|
|
3025
|
+
const newContext = { traceId, spanId, contexts: [] };
|
|
3026
|
+
newStack = [...currentStack, newContext];
|
|
3027
|
+
const inputs = args;
|
|
3028
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3029
|
+
if (isRootSpan && !activeTraceStates.has(traceId)) {
|
|
3030
|
+
const replayCtxAtRoot = getReplayContext();
|
|
3031
|
+
const dbSnapshotRef = buildSnapshotRef(self.dbSnapshot, startedAt);
|
|
3032
|
+
activeTraceStates.set(traceId, {
|
|
3033
|
+
traceId,
|
|
3034
|
+
startedAt,
|
|
3035
|
+
contexts: [],
|
|
3036
|
+
...replayCtxAtRoot?.testRunId && {
|
|
3037
|
+
testRunId: replayCtxAtRoot.testRunId
|
|
3038
|
+
},
|
|
3039
|
+
...replayCtxAtRoot?.inputSourceTraceId && {
|
|
3040
|
+
inputSourceTraceId: replayCtxAtRoot.inputSourceTraceId
|
|
3041
|
+
},
|
|
3042
|
+
dbSnapshotRef
|
|
3043
|
+
});
|
|
3044
|
+
pendingSpanPromises.set(traceId, []);
|
|
3045
|
+
registeredTraceId = traceId;
|
|
3046
|
+
}
|
|
3047
|
+
const functionName = fn.name !== "" ? fn.name : void 0;
|
|
3048
|
+
const baseSpanParams = {
|
|
3049
|
+
traceFunctionKey,
|
|
3050
|
+
functionName,
|
|
3051
|
+
spanName: options.name ?? functionName ?? traceFunctionKey,
|
|
2942
3052
|
traceId,
|
|
3053
|
+
spanId,
|
|
3054
|
+
parentSpanId,
|
|
3055
|
+
inputs,
|
|
2943
3056
|
startedAt,
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
startedAt,
|
|
2965
|
-
spanType: options.type ?? "custom"
|
|
2966
|
-
};
|
|
2967
|
-
const sendSpan = async (params, spanOpts) => {
|
|
2968
|
-
const replayCtx = getReplayContext();
|
|
2969
|
-
const persistenceCollector = isRootSpan ? replayCtx?.pendingPersistence : void 0;
|
|
2970
|
-
let resolvePersistence;
|
|
2971
|
-
if (persistenceCollector && !spanOpts?.skipPersistenceRegistration) {
|
|
2972
|
-
persistenceCollector.push(
|
|
2973
|
-
new Promise((resolve) => {
|
|
2974
|
-
resolvePersistence = resolve;
|
|
2975
|
-
})
|
|
2976
|
-
);
|
|
2977
|
-
}
|
|
2978
|
-
try {
|
|
2979
|
-
const endedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2980
|
-
const spanPromise = self.sendWrapperSpan({
|
|
2981
|
-
...baseSpanParams,
|
|
2982
|
-
...params,
|
|
2983
|
-
contexts: newContext.contexts,
|
|
2984
|
-
prompt: newContext.prompt,
|
|
2985
|
-
endedAt,
|
|
2986
|
-
...replayCtx?.testRunId && { testRunId: replayCtx.testRunId },
|
|
2987
|
-
...replayCtx?.inputSourceSpanId && {
|
|
2988
|
-
inputSourceSpanId: replayCtx.inputSourceSpanId
|
|
2989
|
-
}
|
|
2990
|
-
});
|
|
2991
|
-
if (isRootSpan) {
|
|
2992
|
-
const pending = pendingSpanPromises.get(traceId) ?? [];
|
|
2993
|
-
pending.push(spanPromise);
|
|
2994
|
-
if (persistenceCollector) {
|
|
2995
|
-
await Promise.allSettled(pending);
|
|
2996
|
-
} else {
|
|
2997
|
-
await Promise.race([
|
|
2998
|
-
Promise.allSettled(pending),
|
|
2999
|
-
new Promise((resolve) => setTimeout(resolve, 5e3))
|
|
3000
|
-
]);
|
|
3001
|
-
}
|
|
3002
|
-
pendingSpanPromises.delete(traceId);
|
|
3003
|
-
const traceState = activeTraceStates.get(traceId);
|
|
3004
|
-
const completionPromise = self.sendTraceCompletion({
|
|
3005
|
-
traceFunctionKey,
|
|
3006
|
-
traceId,
|
|
3007
|
-
startedAt: traceState?.startedAt ?? startedAt,
|
|
3057
|
+
spanType: options.type ?? "custom"
|
|
3058
|
+
};
|
|
3059
|
+
const sendSpan = async (params, spanOpts) => {
|
|
3060
|
+
const replayCtx = getReplayContext();
|
|
3061
|
+
const persistenceCollector = isRootSpan ? replayCtx?.pendingPersistence : void 0;
|
|
3062
|
+
let resolvePersistence;
|
|
3063
|
+
if (persistenceCollector && !spanOpts?.skipPersistenceRegistration) {
|
|
3064
|
+
persistenceCollector.push(
|
|
3065
|
+
new Promise((resolve) => {
|
|
3066
|
+
resolvePersistence = resolve;
|
|
3067
|
+
})
|
|
3068
|
+
);
|
|
3069
|
+
}
|
|
3070
|
+
try {
|
|
3071
|
+
const endedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3072
|
+
const spanPromise = self.sendWrapperSpan({
|
|
3073
|
+
...baseSpanParams,
|
|
3074
|
+
...params,
|
|
3075
|
+
contexts: newContext.contexts,
|
|
3076
|
+
prompt: newContext.prompt,
|
|
3008
3077
|
endedAt,
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
testRunId: traceState?.testRunId,
|
|
3013
|
-
inputSourceTraceId: traceState?.inputSourceTraceId,
|
|
3014
|
-
dbSnapshotRef: traceState?.dbSnapshotRef,
|
|
3015
|
-
// Built AFTER the wrapped fn finished, so `accessed` reflects
|
|
3016
|
-
// whether customer code obtained the branch URL during this
|
|
3017
|
-
// item. Omitted entirely when no lease was attached, so the
|
|
3018
|
-
// server can distinguish "no branch" from "branch ignored".
|
|
3019
|
-
...replayCtx?.dbBranchLease && {
|
|
3020
|
-
dbSnapshotUsage: {
|
|
3021
|
-
neonBranchId: replayCtx.dbBranchLease.neonBranchId,
|
|
3022
|
-
snapshotTimestamp: replayCtx.dbBranchLease.snapshotTimestamp,
|
|
3023
|
-
sourceTraceId: replayCtx.sourceBitfabTraceId,
|
|
3024
|
-
accessed: replayCtx.dbSnapshotAccessed === true
|
|
3025
|
-
}
|
|
3078
|
+
...replayCtx?.testRunId && { testRunId: replayCtx.testRunId },
|
|
3079
|
+
...replayCtx?.inputSourceSpanId && {
|
|
3080
|
+
inputSourceSpanId: replayCtx.inputSourceSpanId
|
|
3026
3081
|
}
|
|
3027
3082
|
});
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
await completionPromise;
|
|
3031
|
-
}
|
|
3032
|
-
} else {
|
|
3033
|
-
const pending = pendingSpanPromises.get(traceId);
|
|
3034
|
-
if (pending) {
|
|
3083
|
+
if (isRootSpan) {
|
|
3084
|
+
const pending = pendingSpanPromises.get(traceId) ?? [];
|
|
3035
3085
|
pending.push(spanPromise);
|
|
3086
|
+
if (persistenceCollector) {
|
|
3087
|
+
await Promise.allSettled(pending);
|
|
3088
|
+
} else {
|
|
3089
|
+
let raceTimer;
|
|
3090
|
+
try {
|
|
3091
|
+
await Promise.race([
|
|
3092
|
+
Promise.allSettled(pending),
|
|
3093
|
+
new Promise((resolve) => {
|
|
3094
|
+
raceTimer = setTimeout(resolve, 5e3);
|
|
3095
|
+
unrefTimer(raceTimer);
|
|
3096
|
+
})
|
|
3097
|
+
]);
|
|
3098
|
+
} finally {
|
|
3099
|
+
if (raceTimer) {
|
|
3100
|
+
clearTimeout(raceTimer);
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
}
|
|
3104
|
+
pendingSpanPromises.delete(traceId);
|
|
3105
|
+
const traceState = activeTraceStates.get(traceId);
|
|
3106
|
+
const completionPromise = self.sendTraceCompletion({
|
|
3107
|
+
traceFunctionKey,
|
|
3108
|
+
traceId,
|
|
3109
|
+
startedAt: traceState?.startedAt ?? startedAt,
|
|
3110
|
+
endedAt,
|
|
3111
|
+
sessionId: traceState?.sessionId,
|
|
3112
|
+
metadata: traceState?.metadata,
|
|
3113
|
+
contexts: traceState?.contexts ?? [],
|
|
3114
|
+
testRunId: traceState?.testRunId,
|
|
3115
|
+
inputSourceTraceId: traceState?.inputSourceTraceId,
|
|
3116
|
+
dbSnapshotRef: traceState?.dbSnapshotRef,
|
|
3117
|
+
// Built AFTER the wrapped fn finished, so `accessed` reflects
|
|
3118
|
+
// whether customer code obtained the branch URL during this
|
|
3119
|
+
// item. Omitted entirely when no lease was attached, so the
|
|
3120
|
+
// server can distinguish "no branch" from "branch ignored".
|
|
3121
|
+
...replayCtx?.dbBranchLease && {
|
|
3122
|
+
dbSnapshotUsage: {
|
|
3123
|
+
neonBranchId: replayCtx.dbBranchLease.neonBranchId,
|
|
3124
|
+
snapshotTimestamp: replayCtx.dbBranchLease.snapshotTimestamp,
|
|
3125
|
+
sourceTraceId: replayCtx.sourceBitfabTraceId,
|
|
3126
|
+
accessed: replayCtx.dbSnapshotAccessed === true
|
|
3127
|
+
}
|
|
3128
|
+
}
|
|
3129
|
+
});
|
|
3130
|
+
activeTraceStates.delete(traceId);
|
|
3131
|
+
if (persistenceCollector) {
|
|
3132
|
+
await completionPromise;
|
|
3133
|
+
}
|
|
3036
3134
|
} else {
|
|
3037
|
-
pendingSpanPromises.
|
|
3135
|
+
const pending = pendingSpanPromises.get(traceId);
|
|
3136
|
+
if (pending) {
|
|
3137
|
+
pending.push(spanPromise);
|
|
3138
|
+
} else {
|
|
3139
|
+
pendingSpanPromises.set(traceId, [spanPromise]);
|
|
3140
|
+
}
|
|
3038
3141
|
}
|
|
3142
|
+
} catch {
|
|
3143
|
+
} finally {
|
|
3144
|
+
resolvePersistence?.();
|
|
3039
3145
|
}
|
|
3040
|
-
}
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
if (fnReturnsPromise) {
|
|
3065
|
-
return Promise.resolve(output);
|
|
3146
|
+
};
|
|
3147
|
+
const replayCtxForMock = getReplayContext();
|
|
3148
|
+
if (replayCtxForMock?.mockTree && !isRootSpan) {
|
|
3149
|
+
const counters = replayCtxForMock.callCounters;
|
|
3150
|
+
const counterKey = `${traceFunctionKey}:${baseSpanParams.spanName}`;
|
|
3151
|
+
const callIndex = counters.get(counterKey) ?? 0;
|
|
3152
|
+
counters.set(counterKey, callIndex + 1);
|
|
3153
|
+
const shouldMock = replayCtxForMock.mockStrategy === "all" || replayCtxForMock.mockStrategy === "marked" && options.mockOnReplay === true;
|
|
3154
|
+
if (shouldMock) {
|
|
3155
|
+
const mockKey = `${counterKey}:${callIndex}`;
|
|
3156
|
+
const mockSpan = replayCtxForMock.mockTree.spans.get(mockKey);
|
|
3157
|
+
if (mockSpan) {
|
|
3158
|
+
let output = mockSpan.output;
|
|
3159
|
+
if (mockSpan.outputMeta !== void 0 && mockSpan.outputMeta !== null) {
|
|
3160
|
+
output = deserializeValue({
|
|
3161
|
+
json: mockSpan.output,
|
|
3162
|
+
meta: mockSpan.outputMeta
|
|
3163
|
+
});
|
|
3164
|
+
}
|
|
3165
|
+
void sendSpan({ result: output });
|
|
3166
|
+
if (fnReturnsPromise) {
|
|
3167
|
+
return Promise.resolve(output);
|
|
3168
|
+
}
|
|
3169
|
+
return output;
|
|
3066
3170
|
}
|
|
3067
|
-
return output;
|
|
3068
3171
|
}
|
|
3069
3172
|
}
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3173
|
+
const recordSpan = (result) => {
|
|
3174
|
+
if (options.finalize) {
|
|
3175
|
+
const replayCtx = getReplayContext();
|
|
3176
|
+
const persistenceCollector = isRootSpan ? replayCtx?.pendingPersistence : void 0;
|
|
3177
|
+
let resolvePersistence;
|
|
3178
|
+
if (persistenceCollector) {
|
|
3179
|
+
persistenceCollector.push(
|
|
3180
|
+
new Promise((resolve) => {
|
|
3181
|
+
resolvePersistence = resolve;
|
|
3182
|
+
})
|
|
3183
|
+
);
|
|
3184
|
+
}
|
|
3185
|
+
void Promise.resolve().then(() => options.finalize(result)).then(
|
|
3186
|
+
(output) => sendSpan(
|
|
3187
|
+
{ result: output },
|
|
3188
|
+
{ skipPersistenceRegistration: true }
|
|
3189
|
+
)
|
|
3190
|
+
).catch(
|
|
3191
|
+
(error) => sendSpan(
|
|
3192
|
+
{
|
|
3193
|
+
result: void 0,
|
|
3194
|
+
error: error instanceof Error ? `finalize failed: ${error.message}` : `finalize failed: ${String(error)}`
|
|
3195
|
+
},
|
|
3196
|
+
{ skipPersistenceRegistration: true }
|
|
3197
|
+
)
|
|
3198
|
+
).finally(() => resolvePersistence?.());
|
|
3199
|
+
} else {
|
|
3200
|
+
void sendSpan({ result });
|
|
3082
3201
|
}
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
)
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3202
|
+
};
|
|
3203
|
+
executeWithContext = () => {
|
|
3204
|
+
const result = fn(...args);
|
|
3205
|
+
if (result instanceof Promise) {
|
|
3206
|
+
return result.then((resolvedResult) => {
|
|
3207
|
+
recordSpan(resolvedResult);
|
|
3208
|
+
return resolvedResult;
|
|
3209
|
+
}).catch((error) => {
|
|
3210
|
+
void sendSpan({
|
|
3091
3211
|
result: void 0,
|
|
3092
|
-
error: error instanceof Error ?
|
|
3093
|
-
}
|
|
3094
|
-
|
|
3095
|
-
)
|
|
3096
|
-
).finally(() => resolvePersistence?.());
|
|
3097
|
-
} else {
|
|
3098
|
-
void sendSpan({ result });
|
|
3099
|
-
}
|
|
3100
|
-
};
|
|
3101
|
-
const executeWithContext = () => {
|
|
3102
|
-
const result = fn(...args);
|
|
3103
|
-
if (result instanceof Promise) {
|
|
3104
|
-
return result.then((resolvedResult) => {
|
|
3105
|
-
recordSpan(resolvedResult);
|
|
3106
|
-
return resolvedResult;
|
|
3107
|
-
}).catch((error) => {
|
|
3108
|
-
void sendSpan({
|
|
3109
|
-
result: void 0,
|
|
3110
|
-
error: error instanceof Error ? error.message : String(error)
|
|
3212
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3213
|
+
});
|
|
3214
|
+
throw error;
|
|
3111
3215
|
});
|
|
3112
|
-
|
|
3113
|
-
|
|
3216
|
+
}
|
|
3217
|
+
if (isAsyncGenerator(result)) {
|
|
3218
|
+
return wrapAsyncGenerator(result, newStack, sendSpan);
|
|
3219
|
+
}
|
|
3220
|
+
recordSpan(result);
|
|
3221
|
+
return result;
|
|
3222
|
+
};
|
|
3223
|
+
} catch (setupError) {
|
|
3224
|
+
if (registeredTraceId) {
|
|
3225
|
+
activeTraceStates.delete(registeredTraceId);
|
|
3226
|
+
pendingSpanPromises.delete(registeredTraceId);
|
|
3114
3227
|
}
|
|
3115
|
-
if (
|
|
3116
|
-
|
|
3228
|
+
if (getReplayContext()) {
|
|
3229
|
+
throw setupError;
|
|
3117
3230
|
}
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3231
|
+
warnOnce(
|
|
3232
|
+
`withSpan-setup:${traceFunctionKey}`,
|
|
3233
|
+
`tracing setup failed for "${traceFunctionKey}"; running it untraced. The function still runs and returns normally; no span is recorded.`
|
|
3234
|
+
);
|
|
3235
|
+
return fn(...args);
|
|
3236
|
+
}
|
|
3121
3237
|
return runWithSpanStack(newStack, executeWithContext);
|
|
3122
3238
|
};
|
|
3123
3239
|
Object.defineProperty(wrappedFn, "_bitfabTraceFunctionKey", {
|
|
@@ -3334,7 +3450,7 @@ var Bitfab = class {
|
|
|
3334
3450
|
`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.`
|
|
3335
3451
|
);
|
|
3336
3452
|
}
|
|
3337
|
-
const { replay: doReplay } = await import("./replay-
|
|
3453
|
+
const { replay: doReplay } = await import("./replay-CQIU2ITL.js");
|
|
3338
3454
|
return doReplay(
|
|
3339
3455
|
this.httpClient,
|
|
3340
3456
|
this.serviceUrl,
|
|
@@ -3464,4 +3580,4 @@ export {
|
|
|
3464
3580
|
BitfabFunction,
|
|
3465
3581
|
finalizers
|
|
3466
3582
|
};
|
|
3467
|
-
//# sourceMappingURL=chunk-
|
|
3583
|
+
//# sourceMappingURL=chunk-S3PN26RH.js.map
|