bitfab 0.14.0 → 0.16.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-RMQX546G.js → chunk-53G5GR7B.js} +369 -12
- package/dist/chunk-53G5GR7B.js.map +1 -0
- package/dist/chunk-QT7HWOKU.js +131 -0
- package/dist/chunk-QT7HWOKU.js.map +1 -0
- package/dist/index.cjs +414 -394
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -2
- package/dist/index.d.ts +41 -2
- package/dist/index.js +6 -6
- package/dist/node.cjs +414 -394
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +5 -5
- package/dist/{replay-LNP2K3DN.js → replay-WIBKB3BK.js} +52 -17
- package/dist/replay-WIBKB3BK.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-OW2EJK7T.js +0 -470
- package/dist/chunk-OW2EJK7T.js.map +0 -1
- package/dist/chunk-RMQX546G.js.map +0 -1
- package/dist/replay-LNP2K3DN.js.map +0 -1
package/dist/node.cjs
CHANGED
|
@@ -85,25 +85,6 @@ var init_asyncStorage = __esm({
|
|
|
85
85
|
}
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
// src/version.generated.ts
|
|
89
|
-
var __version__;
|
|
90
|
-
var init_version_generated = __esm({
|
|
91
|
-
"src/version.generated.ts"() {
|
|
92
|
-
"use strict";
|
|
93
|
-
__version__ = "0.14.0";
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
// src/constants.ts
|
|
98
|
-
var DEFAULT_SERVICE_URL;
|
|
99
|
-
var init_constants = __esm({
|
|
100
|
-
"src/constants.ts"() {
|
|
101
|
-
"use strict";
|
|
102
|
-
init_version_generated();
|
|
103
|
-
DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
|
|
107
88
|
// src/errors.ts
|
|
108
89
|
var BitfabError;
|
|
109
90
|
var init_errors = __esm({
|
|
@@ -119,343 +100,6 @@ var init_errors = __esm({
|
|
|
119
100
|
}
|
|
120
101
|
});
|
|
121
102
|
|
|
122
|
-
// src/http.ts
|
|
123
|
-
function awaitOnExit(promise) {
|
|
124
|
-
pendingTracePromises.add(promise);
|
|
125
|
-
void promise.finally(() => {
|
|
126
|
-
pendingTracePromises.delete(promise);
|
|
127
|
-
}).catch(() => {
|
|
128
|
-
});
|
|
129
|
-
return promise;
|
|
130
|
-
}
|
|
131
|
-
async function flushTraces(timeoutMs = 5e3) {
|
|
132
|
-
if (pendingTracePromises.size === 0) {
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
await Promise.race([
|
|
136
|
-
Promise.allSettled(Array.from(pendingTracePromises)),
|
|
137
|
-
new Promise((resolve) => setTimeout(resolve, timeoutMs))
|
|
138
|
-
]);
|
|
139
|
-
}
|
|
140
|
-
var pendingTracePromises, HttpClient;
|
|
141
|
-
var init_http = __esm({
|
|
142
|
-
"src/http.ts"() {
|
|
143
|
-
"use strict";
|
|
144
|
-
init_constants();
|
|
145
|
-
init_errors();
|
|
146
|
-
pendingTracePromises = /* @__PURE__ */ new Set();
|
|
147
|
-
if (typeof process !== "undefined" && process.versions != null && process.versions.node != null) {
|
|
148
|
-
let isFlushing = false;
|
|
149
|
-
process.on("beforeExit", () => {
|
|
150
|
-
if (pendingTracePromises.size > 0 && !isFlushing) {
|
|
151
|
-
isFlushing = true;
|
|
152
|
-
Promise.allSettled(
|
|
153
|
-
Array.from(pendingTracePromises).map(
|
|
154
|
-
(p) => p.catch(() => {
|
|
155
|
-
})
|
|
156
|
-
)
|
|
157
|
-
).then(() => {
|
|
158
|
-
isFlushing = false;
|
|
159
|
-
}).catch(() => {
|
|
160
|
-
isFlushing = false;
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
HttpClient = class {
|
|
166
|
-
constructor(config) {
|
|
167
|
-
this.apiKey = config.apiKey;
|
|
168
|
-
this.serviceUrl = config.serviceUrl;
|
|
169
|
-
this.timeout = config.timeout ?? 12e4;
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Make an HTTP request to the Bitfab API. Defaults to POST; pass
|
|
173
|
-
* `options.method` to use a different verb (e.g. "PATCH").
|
|
174
|
-
*
|
|
175
|
-
* @param endpoint - The API endpoint (without base URL)
|
|
176
|
-
* @param payload - The request body
|
|
177
|
-
* @param options - Optional request options
|
|
178
|
-
* @returns The parsed JSON response
|
|
179
|
-
* @throws {BitfabError} If the request fails
|
|
180
|
-
*/
|
|
181
|
-
async request(endpoint, payload, options) {
|
|
182
|
-
const url = `${this.serviceUrl}${endpoint}`;
|
|
183
|
-
const timeout = options?.timeout ?? this.timeout;
|
|
184
|
-
const method = options?.method ?? "POST";
|
|
185
|
-
const controller = new AbortController();
|
|
186
|
-
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
187
|
-
let body;
|
|
188
|
-
let serializationError;
|
|
189
|
-
try {
|
|
190
|
-
body = JSON.stringify(payload);
|
|
191
|
-
} catch (error) {
|
|
192
|
-
serializationError = error instanceof Error ? error.message : String(error);
|
|
193
|
-
body = JSON.stringify({
|
|
194
|
-
...Object.fromEntries(
|
|
195
|
-
Object.entries(payload).filter(
|
|
196
|
-
([, v]) => typeof v === "string" || typeof v === "number"
|
|
197
|
-
)
|
|
198
|
-
),
|
|
199
|
-
rawSpan: {},
|
|
200
|
-
errors: [
|
|
201
|
-
{ source: "sdk", step: "json_serialize", error: serializationError }
|
|
202
|
-
]
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
try {
|
|
206
|
-
const response = await fetch(url, {
|
|
207
|
-
method,
|
|
208
|
-
headers: {
|
|
209
|
-
"Content-Type": "application/json",
|
|
210
|
-
Authorization: `Bearer ${this.apiKey}`
|
|
211
|
-
},
|
|
212
|
-
body,
|
|
213
|
-
signal: controller.signal
|
|
214
|
-
});
|
|
215
|
-
if (!response.ok) {
|
|
216
|
-
const errorText = await response.text();
|
|
217
|
-
throw new BitfabError(
|
|
218
|
-
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
const result = await response.json();
|
|
222
|
-
if (result.error) {
|
|
223
|
-
if (result.url) {
|
|
224
|
-
throw new BitfabError(
|
|
225
|
-
`${result.error} Configure it at: ${this.serviceUrl}${result.url}`,
|
|
226
|
-
result.url
|
|
227
|
-
);
|
|
228
|
-
}
|
|
229
|
-
throw new BitfabError(result.error);
|
|
230
|
-
}
|
|
231
|
-
return result;
|
|
232
|
-
} catch (error) {
|
|
233
|
-
if (error instanceof BitfabError) {
|
|
234
|
-
throw error;
|
|
235
|
-
}
|
|
236
|
-
if (error instanceof Error) {
|
|
237
|
-
if (error.name === "AbortError") {
|
|
238
|
-
throw new BitfabError(`Request timed out after ${timeout}ms`);
|
|
239
|
-
}
|
|
240
|
-
throw new BitfabError(error.message);
|
|
241
|
-
}
|
|
242
|
-
throw new BitfabError("Unknown error occurred");
|
|
243
|
-
} finally {
|
|
244
|
-
clearTimeout(timeoutId);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Look up a function by name.
|
|
249
|
-
* Blocks until complete - needed for function execution.
|
|
250
|
-
*/
|
|
251
|
-
async lookupFunction(name) {
|
|
252
|
-
return this.request("/api/sdk/functions/lookup", { name });
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Send an internal trace (from BAML execution).
|
|
256
|
-
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
257
|
-
*/
|
|
258
|
-
sendInternalTrace(functionId, payload) {
|
|
259
|
-
void awaitOnExit(
|
|
260
|
-
this.request(`/api/sdk/functions/${functionId}/traces`, {
|
|
261
|
-
...payload,
|
|
262
|
-
sdkVersion: __version__
|
|
263
|
-
})
|
|
264
|
-
).catch((error) => {
|
|
265
|
-
try {
|
|
266
|
-
console.error("Bitfab: Failed to create trace:", error);
|
|
267
|
-
} catch {
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* Send an external span (from withSpan wrapper or OpenAI tracing).
|
|
273
|
-
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
274
|
-
* Returns the tracked promise so callers can optionally await it.
|
|
275
|
-
*/
|
|
276
|
-
sendExternalSpan(payload) {
|
|
277
|
-
return awaitOnExit(
|
|
278
|
-
this.request("/api/sdk/externalSpans", {
|
|
279
|
-
...payload,
|
|
280
|
-
sdkVersion: __version__
|
|
281
|
-
})
|
|
282
|
-
).catch((error) => {
|
|
283
|
-
try {
|
|
284
|
-
console.error("Bitfab: Failed to create external span:", error);
|
|
285
|
-
} catch {
|
|
286
|
-
}
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* Send an external trace (from OpenAI tracing).
|
|
291
|
-
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
292
|
-
*/
|
|
293
|
-
sendExternalTrace(payload) {
|
|
294
|
-
void awaitOnExit(
|
|
295
|
-
this.request("/api/sdk/externalTraces", {
|
|
296
|
-
...payload,
|
|
297
|
-
sdkVersion: __version__
|
|
298
|
-
})
|
|
299
|
-
).catch((error) => {
|
|
300
|
-
try {
|
|
301
|
-
console.error("Bitfab: Failed to create external trace:", error);
|
|
302
|
-
} catch {
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
/**
|
|
307
|
-
* Partial update of an existing external trace identified by sourceTraceId.
|
|
308
|
-
* Used by the detached `client.getTrace(id)` handle. Fire-and-forget;
|
|
309
|
-
* returns a tracked promise that callers may optionally await.
|
|
310
|
-
*/
|
|
311
|
-
patchTrace(sourceTraceId, payload) {
|
|
312
|
-
const endpoint = `/api/sdk/externalTraces/${encodeURIComponent(sourceTraceId)}`;
|
|
313
|
-
return awaitOnExit(
|
|
314
|
-
this.request(endpoint, payload, { method: "PATCH" })
|
|
315
|
-
).catch((error) => {
|
|
316
|
-
try {
|
|
317
|
-
console.error("Bitfab: Failed to patch trace:", error);
|
|
318
|
-
} catch {
|
|
319
|
-
}
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Start a replay session by fetching historical traces.
|
|
324
|
-
* Blocking call — creates a test run and returns lightweight item references.
|
|
325
|
-
*/
|
|
326
|
-
async startReplay(traceFunctionKey, limit, traceIds, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId) {
|
|
327
|
-
const payload = { traceFunctionKey };
|
|
328
|
-
if (limit !== void 0) {
|
|
329
|
-
payload.limit = limit;
|
|
330
|
-
}
|
|
331
|
-
if (traceIds) {
|
|
332
|
-
payload.traceIds = traceIds;
|
|
333
|
-
}
|
|
334
|
-
if (codeChangeDescription !== void 0) {
|
|
335
|
-
payload.codeChangeDescription = codeChangeDescription;
|
|
336
|
-
}
|
|
337
|
-
if (codeChangeFiles !== void 0) {
|
|
338
|
-
payload.codeChangeFiles = codeChangeFiles;
|
|
339
|
-
}
|
|
340
|
-
if (includeDbBranchLease) {
|
|
341
|
-
payload.includeDbBranchLease = true;
|
|
342
|
-
}
|
|
343
|
-
if (experimentGroupId !== void 0) {
|
|
344
|
-
payload.experimentGroupId = experimentGroupId;
|
|
345
|
-
}
|
|
346
|
-
const timeout = includeDbBranchLease ? 18e4 : 3e4;
|
|
347
|
-
return this.request("/api/sdk/replay/start", payload, {
|
|
348
|
-
timeout
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* Fetch an external span by ID.
|
|
353
|
-
* Blocking GET request.
|
|
354
|
-
*/
|
|
355
|
-
async getExternalSpan(spanId) {
|
|
356
|
-
const url = `${this.serviceUrl}/api/sdk/externalSpans/${spanId}`;
|
|
357
|
-
const controller = new AbortController();
|
|
358
|
-
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
359
|
-
try {
|
|
360
|
-
const response = await fetch(url, {
|
|
361
|
-
method: "GET",
|
|
362
|
-
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
363
|
-
signal: controller.signal
|
|
364
|
-
});
|
|
365
|
-
if (!response.ok) {
|
|
366
|
-
const errorText = await response.text();
|
|
367
|
-
throw new BitfabError(
|
|
368
|
-
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
369
|
-
);
|
|
370
|
-
}
|
|
371
|
-
return await response.json();
|
|
372
|
-
} catch (error) {
|
|
373
|
-
if (error instanceof BitfabError) {
|
|
374
|
-
throw error;
|
|
375
|
-
}
|
|
376
|
-
if (error instanceof Error) {
|
|
377
|
-
if (error.name === "AbortError") {
|
|
378
|
-
throw new BitfabError("Request timed out after 30000ms");
|
|
379
|
-
}
|
|
380
|
-
throw new BitfabError(error.message);
|
|
381
|
-
}
|
|
382
|
-
throw new BitfabError("Unknown error occurred");
|
|
383
|
-
} finally {
|
|
384
|
-
clearTimeout(timeoutId);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Fetch the span tree for a root span.
|
|
389
|
-
* Blocking GET request.
|
|
390
|
-
*/
|
|
391
|
-
async getSpanTree(externalSpanId) {
|
|
392
|
-
const url = `${this.serviceUrl}/api/sdk/replay/spanTree/${externalSpanId}`;
|
|
393
|
-
const controller = new AbortController();
|
|
394
|
-
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
395
|
-
try {
|
|
396
|
-
const response = await fetch(url, {
|
|
397
|
-
method: "GET",
|
|
398
|
-
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
399
|
-
signal: controller.signal
|
|
400
|
-
});
|
|
401
|
-
if (!response.ok) {
|
|
402
|
-
const errorText = await response.text();
|
|
403
|
-
throw new BitfabError(
|
|
404
|
-
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
405
|
-
);
|
|
406
|
-
}
|
|
407
|
-
return await response.json();
|
|
408
|
-
} catch (error) {
|
|
409
|
-
if (error instanceof BitfabError) {
|
|
410
|
-
throw error;
|
|
411
|
-
}
|
|
412
|
-
if (error instanceof Error) {
|
|
413
|
-
if (error.name === "AbortError") {
|
|
414
|
-
throw new BitfabError("Request timed out after 30000ms");
|
|
415
|
-
}
|
|
416
|
-
throw new BitfabError(error.message);
|
|
417
|
-
}
|
|
418
|
-
throw new BitfabError("Unknown error occurred");
|
|
419
|
-
} finally {
|
|
420
|
-
clearTimeout(timeoutId);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
/**
|
|
424
|
-
* Mark a replay test run as completed.
|
|
425
|
-
* Blocking call.
|
|
426
|
-
*/
|
|
427
|
-
async completeReplay(testRunId) {
|
|
428
|
-
return this.request(
|
|
429
|
-
"/api/sdk/replay/complete",
|
|
430
|
-
{ testRunId },
|
|
431
|
-
{ timeout: 3e4 }
|
|
432
|
-
);
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
|
-
* Ask the server to materialize a per-trace DB branch lease from a
|
|
436
|
-
* captured `dbSnapshotRef`. Blocking — the resolver creates a Neon
|
|
437
|
-
* snapshot + preview branch and polls operations to readiness, which
|
|
438
|
-
* can take seconds.
|
|
439
|
-
*/
|
|
440
|
-
async resolveDbBranchLease(testRunId, traceId, dbSnapshotRef) {
|
|
441
|
-
return this.request(
|
|
442
|
-
"/api/sdk/replay/resolveDbBranchLease",
|
|
443
|
-
{ testRunId, traceId, dbSnapshotRef },
|
|
444
|
-
{ timeout: 9e4 }
|
|
445
|
-
);
|
|
446
|
-
}
|
|
447
|
-
/** Release a previously-resolved DB branch by deleting its Neon branch. Idempotent server-side. */
|
|
448
|
-
async releaseDbBranchLease(neonBranchId) {
|
|
449
|
-
await this.request(
|
|
450
|
-
"/api/sdk/replay/releaseDbBranchLease",
|
|
451
|
-
{ neonBranchId },
|
|
452
|
-
{ timeout: 3e4 }
|
|
453
|
-
);
|
|
454
|
-
}
|
|
455
|
-
};
|
|
456
|
-
}
|
|
457
|
-
});
|
|
458
|
-
|
|
459
103
|
// src/replayContext.ts
|
|
460
104
|
function getReplayContext() {
|
|
461
105
|
return replayContextStorage?.getStore() ?? null;
|
|
@@ -590,18 +234,25 @@ function buildMockTree(rootNode) {
|
|
|
590
234
|
}
|
|
591
235
|
return { spans };
|
|
592
236
|
}
|
|
593
|
-
async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy, environment) {
|
|
237
|
+
async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy, environment, adaptInputs) {
|
|
594
238
|
const lease = environment ? serverItem.dbBranchLease : void 0;
|
|
595
239
|
let inputs = [];
|
|
596
240
|
let originalOutput;
|
|
597
241
|
let result;
|
|
598
242
|
let error = null;
|
|
599
243
|
const replayedTraceId = crypto.randomUUID();
|
|
244
|
+
const pendingPersistence = [];
|
|
600
245
|
try {
|
|
601
246
|
const span = await httpClient.getExternalSpan(serverItem.externalSpanId);
|
|
602
247
|
const spanData = span.rawData?.span_data ?? {};
|
|
603
248
|
inputs = deserializeInputs(spanData);
|
|
604
249
|
originalOutput = deserializeOutput(spanData);
|
|
250
|
+
if (adaptInputs) {
|
|
251
|
+
inputs = adaptInputs(inputs, {
|
|
252
|
+
traceId: serverItem.traceId,
|
|
253
|
+
sourceSpanId: serverItem.externalSpanId
|
|
254
|
+
});
|
|
255
|
+
}
|
|
605
256
|
let mockTree;
|
|
606
257
|
if (mockStrategy === "all" || mockStrategy === "marked") {
|
|
607
258
|
const treeResponse = await httpClient.getSpanTree(
|
|
@@ -619,7 +270,8 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
|
|
|
619
270
|
mockTree,
|
|
620
271
|
callCounters: mockTree ? /* @__PURE__ */ new Map() : void 0,
|
|
621
272
|
mockStrategy,
|
|
622
|
-
dbBranchLease: lease
|
|
273
|
+
dbBranchLease: lease,
|
|
274
|
+
pendingPersistence
|
|
623
275
|
},
|
|
624
276
|
() => fn(...inputs)
|
|
625
277
|
);
|
|
@@ -627,6 +279,7 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
|
|
|
627
279
|
} catch (e) {
|
|
628
280
|
error = e instanceof Error ? e.message : String(e);
|
|
629
281
|
} finally {
|
|
282
|
+
await Promise.allSettled(pendingPersistence);
|
|
630
283
|
if (lease) {
|
|
631
284
|
try {
|
|
632
285
|
await httpClient.releaseDbBranchLease(lease.neonBranchId);
|
|
@@ -710,24 +363,51 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options) {
|
|
|
710
363
|
fn,
|
|
711
364
|
testRunId,
|
|
712
365
|
mockStrategy,
|
|
713
|
-
options?.environment
|
|
366
|
+
options?.environment,
|
|
367
|
+
options?.adaptInputs
|
|
714
368
|
)
|
|
715
369
|
);
|
|
716
370
|
const resultItems = await mapWithConcurrency(tasks, maxConcurrency);
|
|
717
|
-
await
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
const completeResult = await httpClient.completeReplay(testRunId);
|
|
721
|
-
serverTraceIds = completeResult.traceIds ?? {};
|
|
722
|
-
} catch (e) {
|
|
371
|
+
const completeResult = await httpClient.completeReplay(testRunId);
|
|
372
|
+
const serverTraceIds = completeResult.traceIds;
|
|
373
|
+
if (serverTraceIds === void 0) {
|
|
723
374
|
try {
|
|
724
|
-
console.
|
|
375
|
+
console.warn(
|
|
376
|
+
"Bitfab: server did not return replay trace IDs; item.traceId will be null (server upgrade required for verdict persistence)"
|
|
377
|
+
);
|
|
725
378
|
} catch {
|
|
726
379
|
}
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
380
|
+
for (const item of resultItems) {
|
|
381
|
+
item.traceId = null;
|
|
382
|
+
}
|
|
383
|
+
} else {
|
|
384
|
+
const missing = [];
|
|
385
|
+
let completedCount = 0;
|
|
386
|
+
for (const item of resultItems) {
|
|
387
|
+
if (item.traceId) {
|
|
388
|
+
const mapped = serverTraceIds[item.traceId];
|
|
389
|
+
if (item.error === null) {
|
|
390
|
+
completedCount += 1;
|
|
391
|
+
if (mapped === void 0) {
|
|
392
|
+
missing.push(item.traceId);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
item.traceId = mapped ?? null;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
if (missing.length > 0) {
|
|
399
|
+
const serverCount = completeResult.traceCount !== void 0 ? ` The server persisted ${completeResult.traceCount} trace(s) for this run.` : "";
|
|
400
|
+
if (missing.length === completedCount) {
|
|
401
|
+
throw new BitfabError(
|
|
402
|
+
`Replay completed but the server has no persisted trace for any of the ${completedCount} completed item(s) (testRunId ${testRunId}).${serverCount} Trace uploads were awaited, so either the uploads failed (check for "Bitfab: Failed to create" errors above) or the replayed function is not wrapped with withSpan.`
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
try {
|
|
406
|
+
console.error(
|
|
407
|
+
`Bitfab: server has no persisted trace for ${missing.length} of ${completedCount} completed replay item(s) (testRunId ${testRunId}).${serverCount} Their traceId is null and verdicts cannot be persisted for them. Missing: ${missing.join(", ")}`
|
|
408
|
+
);
|
|
409
|
+
} catch {
|
|
410
|
+
}
|
|
731
411
|
}
|
|
732
412
|
}
|
|
733
413
|
return {
|
|
@@ -740,7 +420,6 @@ var init_replay = __esm({
|
|
|
740
420
|
"src/replay.ts"() {
|
|
741
421
|
"use strict";
|
|
742
422
|
init_errors();
|
|
743
|
-
init_http();
|
|
744
423
|
init_replayContext();
|
|
745
424
|
init_serialize();
|
|
746
425
|
}
|
|
@@ -772,9 +451,346 @@ registerAsyncLocalStorageClass(
|
|
|
772
451
|
import_node_async_hooks.AsyncLocalStorage
|
|
773
452
|
);
|
|
774
453
|
|
|
454
|
+
// src/version.generated.ts
|
|
455
|
+
var __version__ = "0.16.0";
|
|
456
|
+
|
|
457
|
+
// src/constants.ts
|
|
458
|
+
var DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
459
|
+
|
|
460
|
+
// src/http.ts
|
|
461
|
+
init_errors();
|
|
462
|
+
var pendingTracePromises = /* @__PURE__ */ new Set();
|
|
463
|
+
function awaitOnExit(promise) {
|
|
464
|
+
pendingTracePromises.add(promise);
|
|
465
|
+
void promise.finally(() => {
|
|
466
|
+
pendingTracePromises.delete(promise);
|
|
467
|
+
}).catch(() => {
|
|
468
|
+
});
|
|
469
|
+
return promise;
|
|
470
|
+
}
|
|
471
|
+
async function flushTraces(timeoutMs = 5e3) {
|
|
472
|
+
if (pendingTracePromises.size === 0) {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
await Promise.race([
|
|
476
|
+
Promise.allSettled(Array.from(pendingTracePromises)),
|
|
477
|
+
new Promise((resolve) => setTimeout(resolve, timeoutMs))
|
|
478
|
+
]);
|
|
479
|
+
}
|
|
480
|
+
if (typeof process !== "undefined" && process.versions != null && process.versions.node != null) {
|
|
481
|
+
let isFlushing = false;
|
|
482
|
+
process.on("beforeExit", () => {
|
|
483
|
+
if (pendingTracePromises.size > 0 && !isFlushing) {
|
|
484
|
+
isFlushing = true;
|
|
485
|
+
Promise.allSettled(
|
|
486
|
+
Array.from(pendingTracePromises).map(
|
|
487
|
+
(p) => p.catch(() => {
|
|
488
|
+
})
|
|
489
|
+
)
|
|
490
|
+
).then(() => {
|
|
491
|
+
isFlushing = false;
|
|
492
|
+
}).catch(() => {
|
|
493
|
+
isFlushing = false;
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
var HttpClient = class {
|
|
499
|
+
constructor(config) {
|
|
500
|
+
this.apiKey = config.apiKey;
|
|
501
|
+
this.serviceUrl = config.serviceUrl;
|
|
502
|
+
this.timeout = config.timeout ?? 12e4;
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Make an HTTP request to the Bitfab API. Defaults to POST; pass
|
|
506
|
+
* `options.method` to use a different verb (e.g. "PATCH").
|
|
507
|
+
*
|
|
508
|
+
* @param endpoint - The API endpoint (without base URL)
|
|
509
|
+
* @param payload - The request body
|
|
510
|
+
* @param options - Optional request options
|
|
511
|
+
* @returns The parsed JSON response
|
|
512
|
+
* @throws {BitfabError} If the request fails
|
|
513
|
+
*/
|
|
514
|
+
async request(endpoint, payload, options) {
|
|
515
|
+
const url = `${this.serviceUrl}${endpoint}`;
|
|
516
|
+
const timeout = options?.timeout ?? this.timeout;
|
|
517
|
+
const method = options?.method ?? "POST";
|
|
518
|
+
const controller = new AbortController();
|
|
519
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
520
|
+
let body;
|
|
521
|
+
let serializationError;
|
|
522
|
+
try {
|
|
523
|
+
body = JSON.stringify(payload);
|
|
524
|
+
} catch (error) {
|
|
525
|
+
serializationError = error instanceof Error ? error.message : String(error);
|
|
526
|
+
body = JSON.stringify({
|
|
527
|
+
...Object.fromEntries(
|
|
528
|
+
Object.entries(payload).filter(
|
|
529
|
+
([, v]) => typeof v === "string" || typeof v === "number"
|
|
530
|
+
)
|
|
531
|
+
),
|
|
532
|
+
rawSpan: {},
|
|
533
|
+
errors: [
|
|
534
|
+
{ source: "sdk", step: "json_serialize", error: serializationError }
|
|
535
|
+
]
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
try {
|
|
539
|
+
const response = await fetch(url, {
|
|
540
|
+
method,
|
|
541
|
+
headers: {
|
|
542
|
+
"Content-Type": "application/json",
|
|
543
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
544
|
+
},
|
|
545
|
+
body,
|
|
546
|
+
signal: controller.signal
|
|
547
|
+
});
|
|
548
|
+
if (!response.ok) {
|
|
549
|
+
const errorText = await response.text();
|
|
550
|
+
throw new BitfabError(
|
|
551
|
+
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
const result = await response.json();
|
|
555
|
+
if (result.error) {
|
|
556
|
+
if (result.url) {
|
|
557
|
+
throw new BitfabError(
|
|
558
|
+
`${result.error} Configure it at: ${this.serviceUrl}${result.url}`,
|
|
559
|
+
result.url
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
throw new BitfabError(result.error);
|
|
563
|
+
}
|
|
564
|
+
return result;
|
|
565
|
+
} catch (error) {
|
|
566
|
+
if (error instanceof BitfabError) {
|
|
567
|
+
throw error;
|
|
568
|
+
}
|
|
569
|
+
if (error instanceof Error) {
|
|
570
|
+
if (error.name === "AbortError") {
|
|
571
|
+
throw new BitfabError(`Request timed out after ${timeout}ms`);
|
|
572
|
+
}
|
|
573
|
+
throw new BitfabError(error.message);
|
|
574
|
+
}
|
|
575
|
+
throw new BitfabError("Unknown error occurred");
|
|
576
|
+
} finally {
|
|
577
|
+
clearTimeout(timeoutId);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Look up a function by name.
|
|
582
|
+
* Blocks until complete - needed for function execution.
|
|
583
|
+
*/
|
|
584
|
+
async lookupFunction(name) {
|
|
585
|
+
return this.request("/api/sdk/functions/lookup", { name });
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Send an internal trace (from BAML execution).
|
|
589
|
+
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
590
|
+
*/
|
|
591
|
+
sendInternalTrace(functionId, payload) {
|
|
592
|
+
void awaitOnExit(
|
|
593
|
+
this.request(`/api/sdk/functions/${functionId}/traces`, {
|
|
594
|
+
...payload,
|
|
595
|
+
sdkVersion: __version__
|
|
596
|
+
})
|
|
597
|
+
).catch((error) => {
|
|
598
|
+
try {
|
|
599
|
+
console.error("Bitfab: Failed to create trace:", error);
|
|
600
|
+
} catch {
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* Send an external span (from withSpan wrapper or OpenAI tracing).
|
|
606
|
+
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
607
|
+
* Returns the tracked promise so callers can optionally await it.
|
|
608
|
+
*/
|
|
609
|
+
sendExternalSpan(payload) {
|
|
610
|
+
return awaitOnExit(
|
|
611
|
+
this.request("/api/sdk/externalSpans", {
|
|
612
|
+
...payload,
|
|
613
|
+
sdkVersion: __version__
|
|
614
|
+
})
|
|
615
|
+
).catch((error) => {
|
|
616
|
+
try {
|
|
617
|
+
console.error("Bitfab: Failed to create external span:", error);
|
|
618
|
+
} catch {
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Send an external trace (from OpenAI tracing).
|
|
624
|
+
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
625
|
+
* Returns the tracked promise so callers can optionally await it
|
|
626
|
+
* (the replay path does, so trace completions are persisted before
|
|
627
|
+
* `completeReplay` builds the trace-ID mapping).
|
|
628
|
+
*/
|
|
629
|
+
sendExternalTrace(payload) {
|
|
630
|
+
return awaitOnExit(
|
|
631
|
+
this.request("/api/sdk/externalTraces", {
|
|
632
|
+
...payload,
|
|
633
|
+
sdkVersion: __version__
|
|
634
|
+
})
|
|
635
|
+
).catch((error) => {
|
|
636
|
+
try {
|
|
637
|
+
console.error("Bitfab: Failed to create external trace:", error);
|
|
638
|
+
} catch {
|
|
639
|
+
}
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Partial update of an existing external trace identified by sourceTraceId.
|
|
644
|
+
* Used by the detached `client.getTrace(id)` handle. Fire-and-forget;
|
|
645
|
+
* returns a tracked promise that callers may optionally await.
|
|
646
|
+
*/
|
|
647
|
+
patchTrace(sourceTraceId, payload) {
|
|
648
|
+
const endpoint = `/api/sdk/externalTraces/${encodeURIComponent(sourceTraceId)}`;
|
|
649
|
+
return awaitOnExit(
|
|
650
|
+
this.request(endpoint, payload, { method: "PATCH" })
|
|
651
|
+
).catch((error) => {
|
|
652
|
+
try {
|
|
653
|
+
console.error("Bitfab: Failed to patch trace:", error);
|
|
654
|
+
} catch {
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Start a replay session by fetching historical traces.
|
|
660
|
+
* Blocking call — creates a test run and returns lightweight item references.
|
|
661
|
+
*/
|
|
662
|
+
async startReplay(traceFunctionKey, limit, traceIds, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId) {
|
|
663
|
+
const payload = { traceFunctionKey };
|
|
664
|
+
if (limit !== void 0) {
|
|
665
|
+
payload.limit = limit;
|
|
666
|
+
}
|
|
667
|
+
if (traceIds) {
|
|
668
|
+
payload.traceIds = traceIds;
|
|
669
|
+
}
|
|
670
|
+
if (codeChangeDescription !== void 0) {
|
|
671
|
+
payload.codeChangeDescription = codeChangeDescription;
|
|
672
|
+
}
|
|
673
|
+
if (codeChangeFiles !== void 0) {
|
|
674
|
+
payload.codeChangeFiles = codeChangeFiles;
|
|
675
|
+
}
|
|
676
|
+
if (includeDbBranchLease) {
|
|
677
|
+
payload.includeDbBranchLease = true;
|
|
678
|
+
}
|
|
679
|
+
if (experimentGroupId !== void 0) {
|
|
680
|
+
payload.experimentGroupId = experimentGroupId;
|
|
681
|
+
}
|
|
682
|
+
const timeout = includeDbBranchLease ? 18e4 : 3e4;
|
|
683
|
+
return this.request("/api/sdk/replay/start", payload, {
|
|
684
|
+
timeout
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Fetch an external span by ID.
|
|
689
|
+
* Blocking GET request.
|
|
690
|
+
*/
|
|
691
|
+
async getExternalSpan(spanId) {
|
|
692
|
+
const url = `${this.serviceUrl}/api/sdk/externalSpans/${spanId}`;
|
|
693
|
+
const controller = new AbortController();
|
|
694
|
+
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
695
|
+
try {
|
|
696
|
+
const response = await fetch(url, {
|
|
697
|
+
method: "GET",
|
|
698
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
699
|
+
signal: controller.signal
|
|
700
|
+
});
|
|
701
|
+
if (!response.ok) {
|
|
702
|
+
const errorText = await response.text();
|
|
703
|
+
throw new BitfabError(
|
|
704
|
+
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
705
|
+
);
|
|
706
|
+
}
|
|
707
|
+
return await response.json();
|
|
708
|
+
} catch (error) {
|
|
709
|
+
if (error instanceof BitfabError) {
|
|
710
|
+
throw error;
|
|
711
|
+
}
|
|
712
|
+
if (error instanceof Error) {
|
|
713
|
+
if (error.name === "AbortError") {
|
|
714
|
+
throw new BitfabError("Request timed out after 30000ms");
|
|
715
|
+
}
|
|
716
|
+
throw new BitfabError(error.message);
|
|
717
|
+
}
|
|
718
|
+
throw new BitfabError("Unknown error occurred");
|
|
719
|
+
} finally {
|
|
720
|
+
clearTimeout(timeoutId);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Fetch the span tree for a root span.
|
|
725
|
+
* Blocking GET request.
|
|
726
|
+
*/
|
|
727
|
+
async getSpanTree(externalSpanId) {
|
|
728
|
+
const url = `${this.serviceUrl}/api/sdk/replay/spanTree/${externalSpanId}`;
|
|
729
|
+
const controller = new AbortController();
|
|
730
|
+
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
731
|
+
try {
|
|
732
|
+
const response = await fetch(url, {
|
|
733
|
+
method: "GET",
|
|
734
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
735
|
+
signal: controller.signal
|
|
736
|
+
});
|
|
737
|
+
if (!response.ok) {
|
|
738
|
+
const errorText = await response.text();
|
|
739
|
+
throw new BitfabError(
|
|
740
|
+
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
741
|
+
);
|
|
742
|
+
}
|
|
743
|
+
return await response.json();
|
|
744
|
+
} catch (error) {
|
|
745
|
+
if (error instanceof BitfabError) {
|
|
746
|
+
throw error;
|
|
747
|
+
}
|
|
748
|
+
if (error instanceof Error) {
|
|
749
|
+
if (error.name === "AbortError") {
|
|
750
|
+
throw new BitfabError("Request timed out after 30000ms");
|
|
751
|
+
}
|
|
752
|
+
throw new BitfabError(error.message);
|
|
753
|
+
}
|
|
754
|
+
throw new BitfabError("Unknown error occurred");
|
|
755
|
+
} finally {
|
|
756
|
+
clearTimeout(timeoutId);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* Mark a replay test run as completed.
|
|
761
|
+
* Blocking call.
|
|
762
|
+
*/
|
|
763
|
+
async completeReplay(testRunId) {
|
|
764
|
+
return this.request(
|
|
765
|
+
"/api/sdk/replay/complete",
|
|
766
|
+
{ testRunId },
|
|
767
|
+
{ timeout: 3e4 }
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
/**
|
|
771
|
+
* Ask the server to materialize a per-trace DB branch lease from a
|
|
772
|
+
* captured `dbSnapshotRef`. Blocking — the resolver creates a Neon
|
|
773
|
+
* snapshot + preview branch and polls operations to readiness, which
|
|
774
|
+
* can take seconds.
|
|
775
|
+
*/
|
|
776
|
+
async resolveDbBranchLease(testRunId, traceId, dbSnapshotRef) {
|
|
777
|
+
return this.request(
|
|
778
|
+
"/api/sdk/replay/resolveDbBranchLease",
|
|
779
|
+
{ testRunId, traceId, dbSnapshotRef },
|
|
780
|
+
{ timeout: 9e4 }
|
|
781
|
+
);
|
|
782
|
+
}
|
|
783
|
+
/** Release a previously-resolved DB branch by deleting its Neon branch. Idempotent server-side. */
|
|
784
|
+
async releaseDbBranchLease(neonBranchId) {
|
|
785
|
+
await this.request(
|
|
786
|
+
"/api/sdk/replay/releaseDbBranchLease",
|
|
787
|
+
{ neonBranchId },
|
|
788
|
+
{ timeout: 3e4 }
|
|
789
|
+
);
|
|
790
|
+
}
|
|
791
|
+
};
|
|
792
|
+
|
|
775
793
|
// src/claudeAgentSdk.ts
|
|
776
|
-
init_constants();
|
|
777
|
-
init_http();
|
|
778
794
|
function nowIso() {
|
|
779
795
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
780
796
|
}
|
|
@@ -1539,9 +1555,6 @@ async function runFunctionWithBaml(bamlSource, inputs, providers, envVars) {
|
|
|
1539
1555
|
};
|
|
1540
1556
|
}
|
|
1541
1557
|
|
|
1542
|
-
// src/client.ts
|
|
1543
|
-
init_constants();
|
|
1544
|
-
|
|
1545
1558
|
// src/dbSnapshot.ts
|
|
1546
1559
|
init_errors();
|
|
1547
1560
|
var SUPPORTED_PROVIDERS = ["neon"];
|
|
@@ -1559,12 +1572,7 @@ function buildSnapshotRef(config, sdkWallClockBeforeFn) {
|
|
|
1559
1572
|
};
|
|
1560
1573
|
}
|
|
1561
1574
|
|
|
1562
|
-
// src/client.ts
|
|
1563
|
-
init_http();
|
|
1564
|
-
|
|
1565
1575
|
// src/langgraph.ts
|
|
1566
|
-
init_constants();
|
|
1567
|
-
init_http();
|
|
1568
1576
|
var LANGSMITH_HIDDEN_TAG = "langsmith:hidden";
|
|
1569
1577
|
var LANGGRAPH_METADATA_KEYS = [
|
|
1570
1578
|
"langgraph_step",
|
|
@@ -2112,8 +2120,6 @@ var ReplayEnvironment = class {
|
|
|
2112
2120
|
init_serialize();
|
|
2113
2121
|
|
|
2114
2122
|
// src/tracing.ts
|
|
2115
|
-
init_constants();
|
|
2116
|
-
init_http();
|
|
2117
2123
|
var BitfabOpenAITracingProcessor = class {
|
|
2118
2124
|
/**
|
|
2119
2125
|
* Initialize the tracing processor.
|
|
@@ -2947,9 +2953,18 @@ var Bitfab = class {
|
|
|
2947
2953
|
spanType: options.type ?? "custom"
|
|
2948
2954
|
};
|
|
2949
2955
|
const sendSpan = async (params) => {
|
|
2956
|
+
const replayCtx = getReplayContext();
|
|
2957
|
+
const persistenceCollector = isRootSpan ? replayCtx?.pendingPersistence : void 0;
|
|
2958
|
+
let resolvePersistence;
|
|
2959
|
+
if (persistenceCollector) {
|
|
2960
|
+
persistenceCollector.push(
|
|
2961
|
+
new Promise((resolve) => {
|
|
2962
|
+
resolvePersistence = resolve;
|
|
2963
|
+
})
|
|
2964
|
+
);
|
|
2965
|
+
}
|
|
2950
2966
|
try {
|
|
2951
2967
|
const endedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2952
|
-
const replayCtx = getReplayContext();
|
|
2953
2968
|
const spanPromise = self.sendWrapperSpan({
|
|
2954
2969
|
...baseSpanParams,
|
|
2955
2970
|
...params,
|
|
@@ -2964,13 +2979,17 @@ var Bitfab = class {
|
|
|
2964
2979
|
if (isRootSpan) {
|
|
2965
2980
|
const pending = pendingSpanPromises.get(traceId) ?? [];
|
|
2966
2981
|
pending.push(spanPromise);
|
|
2967
|
-
|
|
2968
|
-
Promise.allSettled(pending)
|
|
2969
|
-
|
|
2970
|
-
|
|
2982
|
+
if (persistenceCollector) {
|
|
2983
|
+
await Promise.allSettled(pending);
|
|
2984
|
+
} else {
|
|
2985
|
+
await Promise.race([
|
|
2986
|
+
Promise.allSettled(pending),
|
|
2987
|
+
new Promise((resolve) => setTimeout(resolve, 5e3))
|
|
2988
|
+
]);
|
|
2989
|
+
}
|
|
2971
2990
|
pendingSpanPromises.delete(traceId);
|
|
2972
2991
|
const traceState = activeTraceStates.get(traceId);
|
|
2973
|
-
self.sendTraceCompletion({
|
|
2992
|
+
const completionPromise = self.sendTraceCompletion({
|
|
2974
2993
|
traceFunctionKey,
|
|
2975
2994
|
traceId,
|
|
2976
2995
|
startedAt: traceState?.startedAt ?? startedAt,
|
|
@@ -2983,6 +3002,9 @@ var Bitfab = class {
|
|
|
2983
3002
|
dbSnapshotRef: traceState?.dbSnapshotRef
|
|
2984
3003
|
});
|
|
2985
3004
|
activeTraceStates.delete(traceId);
|
|
3005
|
+
if (persistenceCollector) {
|
|
3006
|
+
await completionPromise;
|
|
3007
|
+
}
|
|
2986
3008
|
} else {
|
|
2987
3009
|
const pending = pendingSpanPromises.get(traceId);
|
|
2988
3010
|
if (pending) {
|
|
@@ -2992,6 +3014,8 @@ var Bitfab = class {
|
|
|
2992
3014
|
}
|
|
2993
3015
|
}
|
|
2994
3016
|
} catch {
|
|
3017
|
+
} finally {
|
|
3018
|
+
resolvePersistence?.();
|
|
2995
3019
|
}
|
|
2996
3020
|
};
|
|
2997
3021
|
const replayCtxForMock = getReplayContext();
|
|
@@ -3144,7 +3168,7 @@ var Bitfab = class {
|
|
|
3144
3168
|
if (params.dbSnapshotRef) {
|
|
3145
3169
|
rawTrace.db_snapshot_ref = params.dbSnapshotRef;
|
|
3146
3170
|
}
|
|
3147
|
-
this.httpClient.sendExternalTrace({
|
|
3171
|
+
return this.httpClient.sendExternalTrace({
|
|
3148
3172
|
type: "sdk-function",
|
|
3149
3173
|
source: "typescript-sdk-function",
|
|
3150
3174
|
traceFunctionKey: params.traceFunctionKey,
|
|
@@ -3289,10 +3313,6 @@ var BitfabFunction = class {
|
|
|
3289
3313
|
}
|
|
3290
3314
|
};
|
|
3291
3315
|
|
|
3292
|
-
// src/index.ts
|
|
3293
|
-
init_constants();
|
|
3294
|
-
init_http();
|
|
3295
|
-
|
|
3296
3316
|
// src/node.ts
|
|
3297
3317
|
init_asyncStorage();
|
|
3298
3318
|
assertAsyncStorageRegistered();
|