bitfab 0.53.0 → 0.53.1
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-6IMGAODW.js → chunk-ASMHSKFS.js} +542 -32
- package/dist/chunk-ASMHSKFS.js.map +1 -0
- package/dist/{chunk-SJKWUQ3G.js → chunk-MMT5MWG5.js} +2 -2
- package/dist/{chunk-SCXR43UF.js → chunk-ZCOZHNAA.js} +101 -42
- package/dist/chunk-ZCOZHNAA.js.map +1 -0
- package/dist/{chunk-DTC6SIXW.js → chunk-ZEGNMZU7.js} +3 -3
- package/dist/{chunk-CBRO6BP7.js → chunk-ZNY2HZT3.js} +141 -29
- package/dist/chunk-ZNY2HZT3.js.map +1 -0
- package/dist/{http-SEN3PUXX.js → http-2OOKOZQ3.js} +2 -2
- package/dist/{http-KP7DVTOD.js → http-7QLUPC6F.js} +2 -2
- package/dist/index.cjs +681 -88
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -8
- package/dist/index.d.ts +25 -8
- package/dist/index.js +3 -3
- package/dist/node.cjs +681 -88
- package/dist/node.cjs.map +1 -1
- package/dist/node.js +3 -3
- package/dist/{replay-Y5RIJOWE.js → replay-KJKIGXRH.js} +3 -3
- package/dist/replayCli.js +2 -2
- package/dist/seedCli.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-6IMGAODW.js.map +0 -1
- package/dist/chunk-CBRO6BP7.js.map +0 -1
- package/dist/chunk-SCXR43UF.js.map +0 -1
- /package/dist/{chunk-SJKWUQ3G.js.map → chunk-MMT5MWG5.js.map} +0 -0
- /package/dist/{chunk-DTC6SIXW.js.map → chunk-ZEGNMZU7.js.map} +0 -0
- /package/dist/{http-KP7DVTOD.js.map → http-2OOKOZQ3.js.map} +0 -0
- /package/dist/{http-SEN3PUXX.js.map → http-7QLUPC6F.js.map} +0 -0
- /package/dist/{replay-Y5RIJOWE.js.map → replay-KJKIGXRH.js.map} +0 -0
|
@@ -99,7 +99,7 @@ function encodeRequestBody(body) {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
// src/version.generated.ts
|
|
102
|
-
var __version__ = "0.53.
|
|
102
|
+
var __version__ = "0.53.1";
|
|
103
103
|
var __packageName__ = "bitfab";
|
|
104
104
|
|
|
105
105
|
// src/constants.ts
|
|
@@ -385,8 +385,8 @@ function encodePayloadBody(payload) {
|
|
|
385
385
|
const marker = { error: `payload_serialize_failed: ${message}` };
|
|
386
386
|
return { body: JSON.stringify(marker), dropped, value: marker };
|
|
387
387
|
}
|
|
388
|
-
const
|
|
389
|
-
if (dropped.length > 0 &&
|
|
388
|
+
const isRecord3 = typeof sanitized === "object" && sanitized !== null && !Array.isArray(sanitized);
|
|
389
|
+
if (dropped.length > 0 && isRecord3) {
|
|
390
390
|
const obj = sanitized;
|
|
391
391
|
const existing = Array.isArray(obj.errors) ? obj.errors : [];
|
|
392
392
|
obj.errors = [
|
|
@@ -403,11 +403,431 @@ function encodePayloadBody(payload) {
|
|
|
403
403
|
return {
|
|
404
404
|
body: JSON.stringify(sanitized),
|
|
405
405
|
dropped,
|
|
406
|
-
value:
|
|
406
|
+
value: isRecord3 ? sanitized : void 0
|
|
407
407
|
};
|
|
408
408
|
}
|
|
409
409
|
}
|
|
410
410
|
|
|
411
|
+
// src/policyRefresh.ts
|
|
412
|
+
var PolicyRefresh = class {
|
|
413
|
+
constructor() {
|
|
414
|
+
this.refreshAfter = 0;
|
|
415
|
+
}
|
|
416
|
+
due() {
|
|
417
|
+
return this.inFlight === void 0 && Date.now() >= this.refreshAfter;
|
|
418
|
+
}
|
|
419
|
+
hold(durationMs) {
|
|
420
|
+
this.refreshAfter = Date.now() + durationMs;
|
|
421
|
+
}
|
|
422
|
+
releaseHold() {
|
|
423
|
+
this.refreshAfter = 0;
|
|
424
|
+
}
|
|
425
|
+
run(read, onLoaded, onFailed) {
|
|
426
|
+
if (!this.due()) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
let request;
|
|
430
|
+
try {
|
|
431
|
+
request = read().then(onLoaded).catch(onFailed).finally(() => {
|
|
432
|
+
this.inFlight = void 0;
|
|
433
|
+
});
|
|
434
|
+
} catch (error) {
|
|
435
|
+
onFailed(error);
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
this.inFlight = request;
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
// src/spanOrigin.ts
|
|
443
|
+
var SPAN_ORIGIN_NAME = "bitfab.sdk.typescript";
|
|
444
|
+
var SPAN_INSTRUMENTATIONS = [
|
|
445
|
+
"span",
|
|
446
|
+
"trace",
|
|
447
|
+
"openai-agents",
|
|
448
|
+
"langgraph",
|
|
449
|
+
"claude-agent-sdk",
|
|
450
|
+
"vercel-ai"
|
|
451
|
+
];
|
|
452
|
+
var FRAMEWORK_INSTRUMENTATIONS = [
|
|
453
|
+
"openai-agents",
|
|
454
|
+
"langgraph",
|
|
455
|
+
"claude-agent-sdk",
|
|
456
|
+
"vercel-ai"
|
|
457
|
+
];
|
|
458
|
+
var FRAMEWORK_INSTRUMENTATION_SET = new Set(
|
|
459
|
+
FRAMEWORK_INSTRUMENTATIONS
|
|
460
|
+
);
|
|
461
|
+
function isFrameworkInstrumentation(value) {
|
|
462
|
+
return typeof value === "string" && FRAMEWORK_INSTRUMENTATION_SET.has(value);
|
|
463
|
+
}
|
|
464
|
+
function makeSpanOrigin(instrumentation) {
|
|
465
|
+
return {
|
|
466
|
+
name: SPAN_ORIGIN_NAME,
|
|
467
|
+
version: __version__,
|
|
468
|
+
instrumentation: { name: instrumentation }
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
function isRecord(value) {
|
|
472
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
473
|
+
}
|
|
474
|
+
function spanOriginOf(payload) {
|
|
475
|
+
const rawSpan = payload.rawSpan;
|
|
476
|
+
if (!isRecord(rawSpan)) {
|
|
477
|
+
return void 0;
|
|
478
|
+
}
|
|
479
|
+
const origin = rawSpan.span_origin;
|
|
480
|
+
if (!isRecord(origin) || !isRecord(origin.instrumentation)) {
|
|
481
|
+
return void 0;
|
|
482
|
+
}
|
|
483
|
+
const { name, version } = origin;
|
|
484
|
+
const instrumentation = origin.instrumentation.name;
|
|
485
|
+
if (typeof name !== "string" || typeof version !== "string" || typeof instrumentation !== "string" || !SPAN_INSTRUMENTATIONS.includes(instrumentation)) {
|
|
486
|
+
return void 0;
|
|
487
|
+
}
|
|
488
|
+
return {
|
|
489
|
+
name,
|
|
490
|
+
version,
|
|
491
|
+
instrumentation: { name: instrumentation }
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
function spanInstrumentationOf(payload) {
|
|
495
|
+
return spanOriginOf(payload)?.instrumentation.name;
|
|
496
|
+
}
|
|
497
|
+
function recordedByFramework(payload) {
|
|
498
|
+
return isFrameworkInstrumentation(spanInstrumentationOf(payload));
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// src/unrefTimer.ts
|
|
502
|
+
function unrefTimer(timer) {
|
|
503
|
+
const handle = timer;
|
|
504
|
+
if (typeof handle.unref === "function") {
|
|
505
|
+
handle.unref();
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// src/simulationPlan.ts
|
|
510
|
+
var SIMULATION_PLAN_REFRESH_MS = 6e4;
|
|
511
|
+
var SIMULATION_PLAN_RETRY_MS = 1e4;
|
|
512
|
+
var SIMULATION_PLAN_READ_TIMEOUT_MS = 5e3;
|
|
513
|
+
var SIMULATION_PLAN_MAX_HELD = 1e3;
|
|
514
|
+
var DISABLE_SIMULATION_PLAN_ENV = "BITFAB_DISABLE_SIM_PLAN";
|
|
515
|
+
var ROOT_TRACE_FUNCTION_KEY_FIELD = "rootTraceFunctionKey";
|
|
516
|
+
var CONTENT_OFF_KEY = "content_off_by_simulation_plan";
|
|
517
|
+
var CONTENT_KEYS = ["input", "input_meta", "output", "output_meta"];
|
|
518
|
+
function planWaitSliceMs(timeoutMs) {
|
|
519
|
+
return Math.min(SIMULATION_PLAN_READ_TIMEOUT_MS, Math.max(timeoutMs, 0) / 2);
|
|
520
|
+
}
|
|
521
|
+
function parseSimulationPlan(body) {
|
|
522
|
+
if (typeof body !== "object" || body === null) {
|
|
523
|
+
return null;
|
|
524
|
+
}
|
|
525
|
+
const nodes = body.nodes;
|
|
526
|
+
if (!Array.isArray(nodes)) {
|
|
527
|
+
return null;
|
|
528
|
+
}
|
|
529
|
+
const contentOff = /* @__PURE__ */ new Map();
|
|
530
|
+
for (const node of nodes) {
|
|
531
|
+
if (typeof node !== "object" || node === null) {
|
|
532
|
+
continue;
|
|
533
|
+
}
|
|
534
|
+
const { traceFunctionKey, name, captureContent } = node;
|
|
535
|
+
if (typeof traceFunctionKey !== "string" || typeof name !== "string" || typeof captureContent !== "boolean") {
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
if (captureContent) {
|
|
539
|
+
continue;
|
|
540
|
+
}
|
|
541
|
+
const names = contentOff.get(traceFunctionKey) ?? /* @__PURE__ */ new Set();
|
|
542
|
+
names.add(name);
|
|
543
|
+
contentOff.set(traceFunctionKey, names);
|
|
544
|
+
}
|
|
545
|
+
return contentOff;
|
|
546
|
+
}
|
|
547
|
+
function traceIdOf(payload) {
|
|
548
|
+
const traceId = payload.traceId;
|
|
549
|
+
if (typeof traceId === "string") {
|
|
550
|
+
return traceId;
|
|
551
|
+
}
|
|
552
|
+
const id = payload.id;
|
|
553
|
+
return typeof id === "string" ? id : void 0;
|
|
554
|
+
}
|
|
555
|
+
function isRecord2(value) {
|
|
556
|
+
return typeof value === "object" && value !== null;
|
|
557
|
+
}
|
|
558
|
+
function rawSpanOf(payload) {
|
|
559
|
+
return isRecord2(payload.rawSpan) ? payload.rawSpan : void 0;
|
|
560
|
+
}
|
|
561
|
+
function spanDataOf(payload) {
|
|
562
|
+
const spanData = rawSpanOf(payload)?.span_data;
|
|
563
|
+
return isRecord2(spanData) ? spanData : void 0;
|
|
564
|
+
}
|
|
565
|
+
function spanNameOf(payload) {
|
|
566
|
+
const name = spanDataOf(payload)?.name;
|
|
567
|
+
return typeof name === "string" ? name : void 0;
|
|
568
|
+
}
|
|
569
|
+
function stripContent(payload) {
|
|
570
|
+
const rawSpan = rawSpanOf(payload);
|
|
571
|
+
const spanData = spanDataOf(payload);
|
|
572
|
+
if (rawSpan === void 0 || spanData === void 0) {
|
|
573
|
+
return payload;
|
|
574
|
+
}
|
|
575
|
+
const kept = { ...spanData };
|
|
576
|
+
for (const key of CONTENT_KEYS) {
|
|
577
|
+
delete kept[key];
|
|
578
|
+
}
|
|
579
|
+
kept[CONTENT_OFF_KEY] = true;
|
|
580
|
+
return { ...payload, rawSpan: { ...rawSpan, span_data: kept } };
|
|
581
|
+
}
|
|
582
|
+
function simulationPlanEnvDisabled() {
|
|
583
|
+
const value = readEnv(DISABLE_SIMULATION_PLAN_ENV);
|
|
584
|
+
return typeof value === "string" && value.trim() !== "";
|
|
585
|
+
}
|
|
586
|
+
function missingSimulationPlanEndpoint(error) {
|
|
587
|
+
return error instanceof BitfabError && error.status === 404;
|
|
588
|
+
}
|
|
589
|
+
var SimulationPlan = class {
|
|
590
|
+
constructor(source, enabled = true) {
|
|
591
|
+
this.source = source;
|
|
592
|
+
this.enabled = enabled;
|
|
593
|
+
this.policyRefresh = new PolicyRefresh();
|
|
594
|
+
this.retryPending = false;
|
|
595
|
+
this.waitingForFirstLoad = 0;
|
|
596
|
+
this.held = [];
|
|
597
|
+
this.droppedWhileHolding = 0;
|
|
598
|
+
this.stopped = false;
|
|
599
|
+
this.loaded = new Promise((resolve) => {
|
|
600
|
+
this.resolveLoaded = resolve;
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
disabled() {
|
|
604
|
+
return !this.enabled || simulationPlanEnvDisabled();
|
|
605
|
+
}
|
|
606
|
+
refresh() {
|
|
607
|
+
if (this.stopped || this.disabled()) {
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
this.policyRefresh.run(
|
|
611
|
+
() => this.source.getSimulationPlan(),
|
|
612
|
+
(body) => {
|
|
613
|
+
const parsed = parseSimulationPlan(body);
|
|
614
|
+
if (parsed === null) {
|
|
615
|
+
this.scheduleRetry(
|
|
616
|
+
"sim-plan-unreadable",
|
|
617
|
+
"the sim plan response was not understood"
|
|
618
|
+
);
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
this.markLoaded(parsed);
|
|
622
|
+
},
|
|
623
|
+
(error) => {
|
|
624
|
+
if (missingSimulationPlanEndpoint(error)) {
|
|
625
|
+
this.markLoaded(/* @__PURE__ */ new Map());
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
this.scheduleRetry(
|
|
629
|
+
"sim-plan-unavailable",
|
|
630
|
+
`could not read the sim plan: ${error instanceof Error ? error.message : String(error)}`
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
);
|
|
634
|
+
}
|
|
635
|
+
markLoaded(parsed) {
|
|
636
|
+
if (this.stopped) {
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
this.contentOffByKey = parsed;
|
|
640
|
+
this.policyRefresh.hold(SIMULATION_PLAN_REFRESH_MS);
|
|
641
|
+
this.retryPending = false;
|
|
642
|
+
this.clearRetryTimer();
|
|
643
|
+
this.resolveLoaded?.();
|
|
644
|
+
this.resolveLoaded = void 0;
|
|
645
|
+
this.releaseHeld();
|
|
646
|
+
}
|
|
647
|
+
scheduleRetry(warnKey, reason) {
|
|
648
|
+
if (this.stopped) {
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
this.policyRefresh.hold(SIMULATION_PLAN_RETRY_MS);
|
|
652
|
+
if (this.contentOffByKey !== void 0) {
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
this.retryPending = true;
|
|
656
|
+
warnOnce(
|
|
657
|
+
warnKey,
|
|
658
|
+
`${reason}. Spans are held until the first read succeeds; while a record is held it is retried every ${SIMULATION_PLAN_RETRY_MS / 1e3}s, otherwise on the next span.`
|
|
659
|
+
);
|
|
660
|
+
this.armRetry();
|
|
661
|
+
}
|
|
662
|
+
holdsWork() {
|
|
663
|
+
return this.held.length > 0 || this.waitingForFirstLoad > 0;
|
|
664
|
+
}
|
|
665
|
+
armRetry() {
|
|
666
|
+
if (this.stopped || !this.retryPending || this.retryTimer !== void 0 || !this.holdsWork()) {
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
const timer = setTimeout(() => {
|
|
670
|
+
this.retryTimer = void 0;
|
|
671
|
+
this.policyRefresh.releaseHold();
|
|
672
|
+
this.refresh();
|
|
673
|
+
}, SIMULATION_PLAN_RETRY_MS);
|
|
674
|
+
unrefTimer(timer);
|
|
675
|
+
this.retryTimer = timer;
|
|
676
|
+
}
|
|
677
|
+
clearRetryTimer() {
|
|
678
|
+
if (this.retryTimer !== void 0) {
|
|
679
|
+
clearTimeout(this.retryTimer);
|
|
680
|
+
this.retryTimer = void 0;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
syncRetryTimer() {
|
|
684
|
+
if (this.holdsWork()) {
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
this.clearRetryTimer();
|
|
688
|
+
}
|
|
689
|
+
firstLoad() {
|
|
690
|
+
if (this.contentOffByKey !== void 0 || this.stopped || this.disabled()) {
|
|
691
|
+
return void 0;
|
|
692
|
+
}
|
|
693
|
+
return this.loaded;
|
|
694
|
+
}
|
|
695
|
+
send(payload, traceFunctionKey, submit) {
|
|
696
|
+
this.refresh();
|
|
697
|
+
if (this.stopped || this.disabled() || traceFunctionKey === void 0 || spanNameOf(payload) === void 0 || recordedByFramework(payload)) {
|
|
698
|
+
submit(payload);
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
if (this.contentOffByKey === void 0) {
|
|
702
|
+
this.hold({ payload, traceFunctionKey, submit });
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
this.submitEntry({ payload, traceFunctionKey, submit });
|
|
706
|
+
}
|
|
707
|
+
sendTrace(payload, submit) {
|
|
708
|
+
this.refresh();
|
|
709
|
+
if (this.stopped || this.disabled() || this.contentOffByKey !== void 0 || !this.holdsSpanOfTrace(traceIdOf(payload))) {
|
|
710
|
+
submit(payload);
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
this.hold({ payload, traceFunctionKey: void 0, submit });
|
|
714
|
+
}
|
|
715
|
+
holdsSpanOfTrace(traceId) {
|
|
716
|
+
if (traceId === void 0) {
|
|
717
|
+
return false;
|
|
718
|
+
}
|
|
719
|
+
return this.held.some(
|
|
720
|
+
(entry) => entry.traceFunctionKey !== void 0 && traceIdOf(entry.payload) === traceId
|
|
721
|
+
);
|
|
722
|
+
}
|
|
723
|
+
hold(entry) {
|
|
724
|
+
this.held.push(entry);
|
|
725
|
+
while (this.held.length > SIMULATION_PLAN_MAX_HELD) {
|
|
726
|
+
this.held.shift();
|
|
727
|
+
this.droppedWhileHolding += 1;
|
|
728
|
+
}
|
|
729
|
+
this.armRetry();
|
|
730
|
+
}
|
|
731
|
+
submitEntry(entry) {
|
|
732
|
+
try {
|
|
733
|
+
entry.submit(
|
|
734
|
+
entry.traceFunctionKey === void 0 ? entry.payload : this.apply(entry.payload, entry.traceFunctionKey)
|
|
735
|
+
);
|
|
736
|
+
} catch (error) {
|
|
737
|
+
warnOnce(
|
|
738
|
+
"sim-plan-held-span-dropped",
|
|
739
|
+
`a span held for the sim plan was dropped when released: ${error instanceof Error ? error.message : String(error)}`
|
|
740
|
+
);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
releaseHeld() {
|
|
744
|
+
const held = this.held;
|
|
745
|
+
this.held = [];
|
|
746
|
+
this.syncRetryTimer();
|
|
747
|
+
this.warnDropped();
|
|
748
|
+
for (const entry of held) {
|
|
749
|
+
this.submitEntry(entry);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
warnDropped() {
|
|
753
|
+
if (this.droppedWhileHolding === 0) {
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
const dropped = this.droppedWhileHolding;
|
|
757
|
+
this.droppedWhileHolding = 0;
|
|
758
|
+
warnOnce(
|
|
759
|
+
"sim-plan-held-overflow",
|
|
760
|
+
`${dropped} record(s) were dropped while the sim plan was still loading; at most ${SIMULATION_PLAN_MAX_HELD} are held per client.`
|
|
761
|
+
);
|
|
762
|
+
}
|
|
763
|
+
warnNeverLoaded() {
|
|
764
|
+
if (this.held.length === 0) {
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
767
|
+
warnOnce(
|
|
768
|
+
"sim-plan-never-loaded",
|
|
769
|
+
`${this.held.length} record(s) were not sent because the sim plan never loaded`
|
|
770
|
+
);
|
|
771
|
+
}
|
|
772
|
+
async release(timeoutMs) {
|
|
773
|
+
this.refresh();
|
|
774
|
+
if (this.holdsWork()) {
|
|
775
|
+
await this.waitForFirstLoad(timeoutMs);
|
|
776
|
+
}
|
|
777
|
+
this.warnNeverLoaded();
|
|
778
|
+
this.warnDropped();
|
|
779
|
+
}
|
|
780
|
+
waitForFirstLoad(timeoutMs) {
|
|
781
|
+
const firstLoad = this.firstLoad();
|
|
782
|
+
if (firstLoad === void 0) {
|
|
783
|
+
return Promise.resolve();
|
|
784
|
+
}
|
|
785
|
+
this.waitingForFirstLoad += 1;
|
|
786
|
+
this.armRetry();
|
|
787
|
+
return new Promise((resolve) => {
|
|
788
|
+
let settled = false;
|
|
789
|
+
const finish = () => {
|
|
790
|
+
if (settled) {
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
settled = true;
|
|
794
|
+
this.waitingForFirstLoad -= 1;
|
|
795
|
+
this.syncRetryTimer();
|
|
796
|
+
resolve();
|
|
797
|
+
};
|
|
798
|
+
const timer = setTimeout(finish, Math.max(timeoutMs, 0));
|
|
799
|
+
void firstLoad.then(() => {
|
|
800
|
+
clearTimeout(timer);
|
|
801
|
+
finish();
|
|
802
|
+
});
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
stop() {
|
|
806
|
+
if (this.stopped) {
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
this.stopped = true;
|
|
810
|
+
this.retryPending = false;
|
|
811
|
+
this.clearRetryTimer();
|
|
812
|
+
this.warnNeverLoaded();
|
|
813
|
+
this.held = [];
|
|
814
|
+
this.warnDropped();
|
|
815
|
+
}
|
|
816
|
+
contentOff(traceFunctionKey, spanName) {
|
|
817
|
+
return this.contentOffByKey?.get(traceFunctionKey)?.has(spanName) === true;
|
|
818
|
+
}
|
|
819
|
+
apply(payload, traceFunctionKey) {
|
|
820
|
+
if (recordedByFramework(payload)) {
|
|
821
|
+
return payload;
|
|
822
|
+
}
|
|
823
|
+
const name = spanNameOf(payload);
|
|
824
|
+
if (name === void 0 || !this.contentOff(traceFunctionKey, name)) {
|
|
825
|
+
return payload;
|
|
826
|
+
}
|
|
827
|
+
return stripContent(payload);
|
|
828
|
+
}
|
|
829
|
+
};
|
|
830
|
+
|
|
411
831
|
// src/traceMetadata.ts
|
|
412
832
|
var RETAINED_COMPLETED_TRACES = 128;
|
|
413
833
|
var activeRecords = /* @__PURE__ */ new Map();
|
|
@@ -523,14 +943,6 @@ var DeliveryError = class extends Error {
|
|
|
523
943
|
}
|
|
524
944
|
};
|
|
525
945
|
|
|
526
|
-
// src/unrefTimer.ts
|
|
527
|
-
function unrefTimer(timer) {
|
|
528
|
-
const handle = timer;
|
|
529
|
-
if (typeof handle.unref === "function") {
|
|
530
|
-
handle.unref();
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
|
|
534
946
|
// src/otel.ts
|
|
535
947
|
var OPERATION_ATTRIBUTE = "bitfab.operation";
|
|
536
948
|
var PAYLOAD_ATTRIBUTE = "bitfab.payload";
|
|
@@ -1153,6 +1565,18 @@ var RETRYABLE_STATUSES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
|
1153
1565
|
var EXIT_FLUSH_TIMEOUT_MS = 5e3;
|
|
1154
1566
|
var DEFAULT_LIFECYCLE_TIMEOUT_MS2 = 3e4;
|
|
1155
1567
|
var pendingTracePromises = /* @__PURE__ */ new Set();
|
|
1568
|
+
var liveHttpClients = /* @__PURE__ */ new Set();
|
|
1569
|
+
async function releaseHeldExternalSpans(timeoutMs) {
|
|
1570
|
+
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1571
|
+
for (const client of [...liveHttpClients]) {
|
|
1572
|
+
await client.releaseHeldExternalSpans?.(Math.max(0, deadline - Date.now()));
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
function stopSimulationPlans() {
|
|
1576
|
+
for (const client of [...liveHttpClients]) {
|
|
1577
|
+
client.stopSimulationPlan?.();
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1156
1580
|
function awaitOnExit(promise) {
|
|
1157
1581
|
pendingTracePromises.add(promise);
|
|
1158
1582
|
void promise.finally(() => {
|
|
@@ -1163,7 +1587,10 @@ function awaitOnExit(promise) {
|
|
|
1163
1587
|
}
|
|
1164
1588
|
async function flushTraces(timeoutMs = 5e3) {
|
|
1165
1589
|
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1166
|
-
|
|
1590
|
+
await releaseHeldExternalSpans(planWaitSliceMs(timeoutMs));
|
|
1591
|
+
const requestsFlushed = await awaitPendingRequests(
|
|
1592
|
+
Math.max(0, deadline - Date.now())
|
|
1593
|
+
);
|
|
1167
1594
|
const transportsFlushed = await flushTraceTransports(
|
|
1168
1595
|
Math.max(0, deadline - Date.now())
|
|
1169
1596
|
);
|
|
@@ -1200,12 +1627,27 @@ if (typeof process !== "undefined" && process.versions != null && process.versio
|
|
|
1200
1627
|
return;
|
|
1201
1628
|
}
|
|
1202
1629
|
isFlushing = true;
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
})),
|
|
1206
|
-
shutdownTraceTransports(EXIT_FLUSH_TIMEOUT_MS).catch(() => false)
|
|
1207
|
-
]).then(() => {
|
|
1630
|
+
const planWaitMs = SIMULATION_PLAN_READ_TIMEOUT_MS;
|
|
1631
|
+
const stopFlushing = () => {
|
|
1208
1632
|
isFlushing = false;
|
|
1633
|
+
};
|
|
1634
|
+
const deadline = setTimeout(
|
|
1635
|
+
stopFlushing,
|
|
1636
|
+
EXIT_FLUSH_TIMEOUT_MS + planWaitMs
|
|
1637
|
+
);
|
|
1638
|
+
unrefTimer(deadline);
|
|
1639
|
+
void releaseHeldExternalSpans(planWaitMs).catch(() => {
|
|
1640
|
+
}).then(() => {
|
|
1641
|
+
stopSimulationPlans();
|
|
1642
|
+
}).then(
|
|
1643
|
+
() => Promise.allSettled([
|
|
1644
|
+
...Array.from(pendingTracePromises).map((p) => p.catch(() => {
|
|
1645
|
+
})),
|
|
1646
|
+
shutdownTraceTransports(EXIT_FLUSH_TIMEOUT_MS).catch(() => false)
|
|
1647
|
+
])
|
|
1648
|
+
).then(() => {
|
|
1649
|
+
clearTimeout(deadline);
|
|
1650
|
+
stopFlushing();
|
|
1209
1651
|
});
|
|
1210
1652
|
});
|
|
1211
1653
|
}
|
|
@@ -1299,6 +1741,21 @@ function sourceTraceIdOf(payload) {
|
|
|
1299
1741
|
return typeof id === "string" ? id : void 0;
|
|
1300
1742
|
}
|
|
1301
1743
|
var carrierSeq = 0;
|
|
1744
|
+
function describeError(error) {
|
|
1745
|
+
return error instanceof Error ? error.message : String(error);
|
|
1746
|
+
}
|
|
1747
|
+
function warnDroppedExternalSpan(error) {
|
|
1748
|
+
warnOnce(
|
|
1749
|
+
"external-span-dropped",
|
|
1750
|
+
`a span was dropped because the send step failed: ${describeError(error)}`
|
|
1751
|
+
);
|
|
1752
|
+
}
|
|
1753
|
+
function warnDroppedExternalTrace(error) {
|
|
1754
|
+
warnOnce(
|
|
1755
|
+
"external-trace-dropped",
|
|
1756
|
+
`a trace was dropped because the send step failed: ${describeError(error)}`
|
|
1757
|
+
);
|
|
1758
|
+
}
|
|
1302
1759
|
var HttpClient = class {
|
|
1303
1760
|
constructor(config) {
|
|
1304
1761
|
// Only traces a caller asked about are tracked, so ordinary tracing stores
|
|
@@ -1313,6 +1770,7 @@ var HttpClient = class {
|
|
|
1313
1770
|
this.apiKey = config.apiKey;
|
|
1314
1771
|
this.serviceUrl = config.serviceUrl;
|
|
1315
1772
|
this.timeout = config.timeout ?? 12e4;
|
|
1773
|
+
liveHttpClients.add(this);
|
|
1316
1774
|
}
|
|
1317
1775
|
/**
|
|
1318
1776
|
* Resolve the API key at the moment it is needed (request time), invoking
|
|
@@ -1510,9 +1968,14 @@ var HttpClient = class {
|
|
|
1510
1968
|
* attributing its timeout here would fail a client whose own work succeeded.
|
|
1511
1969
|
*/
|
|
1512
1970
|
async settleDeferredWork(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS2) {
|
|
1971
|
+
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1972
|
+
await this.releaseHeldExternalSpans?.(planWaitSliceMs(timeoutMs));
|
|
1513
1973
|
await replayContextReady.catch(() => {
|
|
1514
1974
|
});
|
|
1515
|
-
return waitForPromises(
|
|
1975
|
+
return waitForPromises(
|
|
1976
|
+
Array.from(this.deferredWork),
|
|
1977
|
+
Math.max(0, deadline - Date.now())
|
|
1978
|
+
);
|
|
1516
1979
|
}
|
|
1517
1980
|
/**
|
|
1518
1981
|
* Wait for spans queued by this client to be delivered, within one deadline.
|
|
@@ -1520,7 +1983,9 @@ var HttpClient = class {
|
|
|
1520
1983
|
*/
|
|
1521
1984
|
async waitForPendingRequests(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS2) {
|
|
1522
1985
|
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1523
|
-
const settled = await this.settleDeferredWork(
|
|
1986
|
+
const settled = await this.settleDeferredWork(
|
|
1987
|
+
Math.max(0, deadline - Date.now())
|
|
1988
|
+
);
|
|
1524
1989
|
const flushed = await this.traceTransport?.flush(Math.max(0, deadline - Date.now())) ?? true;
|
|
1525
1990
|
return settled && flushed;
|
|
1526
1991
|
}
|
|
@@ -1535,6 +2000,13 @@ var HttpClient = class {
|
|
|
1535
2000
|
}
|
|
1536
2001
|
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1537
2002
|
this.closing = (async () => {
|
|
2003
|
+
await this.releaseHeldExternalSpans?.(planWaitSliceMs(timeoutMs));
|
|
2004
|
+
this.stopSimulationPlan?.();
|
|
2005
|
+
this.externalSpanTransform = void 0;
|
|
2006
|
+
this.externalTraceTransform = void 0;
|
|
2007
|
+
this.releaseHeldExternalSpans = void 0;
|
|
2008
|
+
this.stopSimulationPlan = void 0;
|
|
2009
|
+
liveHttpClients.delete(this);
|
|
1538
2010
|
const settled = await this.settleDeferredWork(
|
|
1539
2011
|
Math.max(0, deadline - Date.now())
|
|
1540
2012
|
);
|
|
@@ -1646,6 +2118,13 @@ var HttpClient = class {
|
|
|
1646
2118
|
protocol
|
|
1647
2119
|
});
|
|
1648
2120
|
}
|
|
2121
|
+
async getSimulationPlan() {
|
|
2122
|
+
return this.get(
|
|
2123
|
+
"/api/sdk/sim-plan",
|
|
2124
|
+
SIMULATION_PLAN_READ_TIMEOUT_MS,
|
|
2125
|
+
{ Connection: "close" }
|
|
2126
|
+
);
|
|
2127
|
+
}
|
|
1649
2128
|
async getTraceSpan(traceId, lookup) {
|
|
1650
2129
|
const searchParams = new URLSearchParams();
|
|
1651
2130
|
if (lookup.id !== void 0) {
|
|
@@ -1662,14 +2141,18 @@ var HttpClient = class {
|
|
|
1662
2141
|
* GET a JSON endpoint on the service with the client's API key. Throws a
|
|
1663
2142
|
* `BitfabError` carrying the status text for any non-2xx response.
|
|
1664
2143
|
*/
|
|
1665
|
-
async get(endpoint) {
|
|
2144
|
+
async get(endpoint, timeoutMs, extraHeaders) {
|
|
1666
2145
|
const url = `${this.serviceUrl}${endpoint}`;
|
|
2146
|
+
const timeout = timeoutMs ?? this.timeout;
|
|
1667
2147
|
const controller = new AbortController();
|
|
1668
|
-
const timeoutId = setTimeout(() => controller.abort(),
|
|
2148
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1669
2149
|
try {
|
|
1670
2150
|
const response = await fetch(url, {
|
|
1671
2151
|
method: "GET",
|
|
1672
|
-
headers: {
|
|
2152
|
+
headers: {
|
|
2153
|
+
Authorization: `Bearer ${this.resolveApiKey() ?? ""}`,
|
|
2154
|
+
...extraHeaders
|
|
2155
|
+
},
|
|
1673
2156
|
signal: controller.signal
|
|
1674
2157
|
});
|
|
1675
2158
|
if (!response.ok) {
|
|
@@ -1688,7 +2171,7 @@ var HttpClient = class {
|
|
|
1688
2171
|
}
|
|
1689
2172
|
if (error instanceof Error) {
|
|
1690
2173
|
if (error.name === "AbortError") {
|
|
1691
|
-
throw new BitfabError(`Request timed out after ${
|
|
2174
|
+
throw new BitfabError(`Request timed out after ${timeout}ms`);
|
|
1692
2175
|
}
|
|
1693
2176
|
throw new BitfabError(error.message);
|
|
1694
2177
|
}
|
|
@@ -1715,16 +2198,27 @@ var HttpClient = class {
|
|
|
1715
2198
|
carrierMeta("internal_trace", body, void 0)
|
|
1716
2199
|
);
|
|
1717
2200
|
}
|
|
1718
|
-
/**
|
|
1719
|
-
* Queue an external span (from withSpan wrapper or OpenAI tracing) onto this
|
|
1720
|
-
* client's batching transport. Fire-and-forget: the transport owns delivery,
|
|
1721
|
-
* so callers await `flushTraces()` or `close()` rather than a per-span
|
|
1722
|
-
* promise.
|
|
1723
|
-
*/
|
|
1724
2201
|
sendExternalSpan(payload) {
|
|
2202
|
+
const gate = this.externalSpanTransform;
|
|
2203
|
+
if (gate === void 0) {
|
|
2204
|
+
this.submitExternalSpan(payload);
|
|
2205
|
+
return;
|
|
2206
|
+
}
|
|
2207
|
+
try {
|
|
2208
|
+
gate(payload, (ready) => this.submitExternalSpan(ready));
|
|
2209
|
+
} catch (error) {
|
|
2210
|
+
warnDroppedExternalSpan(error);
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
submitExternalSpan(payload) {
|
|
2214
|
+
const body = {
|
|
2215
|
+
...payload,
|
|
2216
|
+
sdkVersion: __version__
|
|
2217
|
+
};
|
|
2218
|
+
delete body[ROOT_TRACE_FUNCTION_KEY_FIELD];
|
|
1725
2219
|
this.getTraceTransport()?.submit(
|
|
1726
2220
|
"external_span",
|
|
1727
|
-
|
|
2221
|
+
body,
|
|
1728
2222
|
this.recordedMeta("external_span", payload, carrierRef(payload))
|
|
1729
2223
|
);
|
|
1730
2224
|
}
|
|
@@ -1736,6 +2230,18 @@ var HttpClient = class {
|
|
|
1736
2230
|
*/
|
|
1737
2231
|
sendExternalTrace(rawPayload) {
|
|
1738
2232
|
const payload = mergeCallerMetadataIntoTracePayload(rawPayload);
|
|
2233
|
+
const gate = this.externalTraceTransform;
|
|
2234
|
+
if (gate === void 0) {
|
|
2235
|
+
this.submitExternalTrace(payload);
|
|
2236
|
+
return;
|
|
2237
|
+
}
|
|
2238
|
+
try {
|
|
2239
|
+
gate(payload, (ready) => this.submitExternalTrace(ready));
|
|
2240
|
+
} catch (error) {
|
|
2241
|
+
warnDroppedExternalTrace(error);
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
submitExternalTrace(payload) {
|
|
1739
2245
|
this.getTraceTransport()?.submit(
|
|
1740
2246
|
"external_trace",
|
|
1741
2247
|
{
|
|
@@ -1983,6 +2489,10 @@ export {
|
|
|
1983
2489
|
MAX_COMPRESSIBLE_SPAN_CARRIER_BYTES,
|
|
1984
2490
|
warnOnce,
|
|
1985
2491
|
serializePayloadBody,
|
|
2492
|
+
PolicyRefresh,
|
|
2493
|
+
makeSpanOrigin,
|
|
2494
|
+
ROOT_TRACE_FUNCTION_KEY_FIELD,
|
|
2495
|
+
SimulationPlan,
|
|
1986
2496
|
recordCallerTraceMetadata,
|
|
1987
2497
|
callerTraceMetadata,
|
|
1988
2498
|
retireTraceMetadata,
|
|
@@ -1992,4 +2502,4 @@ export {
|
|
|
1992
2502
|
parseRetryAfterMs,
|
|
1993
2503
|
HttpClient
|
|
1994
2504
|
};
|
|
1995
|
-
//# sourceMappingURL=chunk-
|
|
2505
|
+
//# sourceMappingURL=chunk-ASMHSKFS.js.map
|