bitfab 0.54.13 → 0.57.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.
Files changed (34) hide show
  1. package/dist/{chunk-VW7MA7DS.js → chunk-3KWRBX56.js} +29 -17
  2. package/dist/chunk-3KWRBX56.js.map +1 -0
  3. package/dist/{chunk-Q7HDNYYY.js → chunk-56USYDIX.js} +143 -34
  4. package/dist/chunk-56USYDIX.js.map +1 -0
  5. package/dist/{chunk-KPALXSAF.js → chunk-FZNBGX2R.js} +37 -7
  6. package/dist/chunk-FZNBGX2R.js.map +1 -0
  7. package/dist/{chunk-FZNRSEMN.js → chunk-JEN5MX7A.js} +9 -3
  8. package/dist/chunk-JEN5MX7A.js.map +1 -0
  9. package/dist/{chunk-YKOD4GWI.js → chunk-YE75OWXI.js} +136 -110
  10. package/dist/chunk-YE75OWXI.js.map +1 -0
  11. package/dist/{http-7PF6XCJR.js → http-33ALYZUK.js} +2 -2
  12. package/dist/{http-42KAFBUN.js → http-HKMIFNAR.js} +2 -2
  13. package/dist/index.cjs +276 -146
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.cts +12 -5
  16. package/dist/index.d.ts +12 -5
  17. package/dist/index.js +3 -3
  18. package/dist/node.cjs +276 -146
  19. package/dist/node.cjs.map +1 -1
  20. package/dist/node.d.cts +1 -1
  21. package/dist/node.d.ts +1 -1
  22. package/dist/node.js +3 -3
  23. package/dist/{replay-5RHBDIEK.js → replay-JCY64EHP.js} +3 -3
  24. package/dist/replayCli.js +2 -2
  25. package/dist/seedCli.js +2 -2
  26. package/package.json +1 -1
  27. package/dist/chunk-FZNRSEMN.js.map +0 -1
  28. package/dist/chunk-KPALXSAF.js.map +0 -1
  29. package/dist/chunk-Q7HDNYYY.js.map +0 -1
  30. package/dist/chunk-VW7MA7DS.js.map +0 -1
  31. package/dist/chunk-YKOD4GWI.js.map +0 -1
  32. /package/dist/{http-42KAFBUN.js.map → http-33ALYZUK.js.map} +0 -0
  33. /package/dist/{http-7PF6XCJR.js.map → http-HKMIFNAR.js.map} +0 -0
  34. /package/dist/{replay-5RHBDIEK.js.map → replay-JCY64EHP.js.map} +0 -0
@@ -187,7 +187,7 @@ function encodeRequestBody(body) {
187
187
  }
188
188
 
189
189
  // src/version.generated.ts
190
- var __version__ = "0.54.13";
190
+ var __version__ = "0.57.0";
191
191
  var __packageName__ = "bitfab";
192
192
 
193
193
  // src/constants.ts
@@ -780,14 +780,6 @@ function recordedByFramework(payload) {
780
780
  return isFrameworkInstrumentation(spanInstrumentationOf(payload));
781
781
  }
782
782
 
783
- // src/unrefTimer.ts
784
- function unrefTimer(timer) {
785
- const handle = timer;
786
- if (typeof handle.unref === "function") {
787
- handle.unref();
788
- }
789
- }
790
-
791
783
  // src/simulationPlan.ts
792
784
  var SIMULATION_PLAN_REFRESH_MS = 6e4;
793
785
  var SIMULATION_PLAN_RETRY_MS = 1e4;
@@ -868,19 +860,25 @@ function simulationPlanEnvDisabled() {
868
860
  function missingSimulationPlanEndpoint(error) {
869
861
  return error instanceof BitfabError && error.status === 404;
870
862
  }
863
+ function isTraceRootSpan(payload) {
864
+ const parentId = rawSpanOf(payload)?.parent_id;
865
+ return parentId === void 0 || parentId === null;
866
+ }
871
867
  var SimulationPlan = class {
872
868
  constructor(source, enabled = true) {
873
869
  this.source = source;
874
870
  this.enabled = enabled;
875
871
  this.policyRefresh = new PolicyRefresh();
876
- this.retryPending = false;
877
- this.waitingForFirstLoad = 0;
872
+ this.firstReadOver = false;
873
+ this.rootWaitOver = false;
878
874
  this.held = [];
879
- this.droppedWhileHolding = 0;
880
875
  this.stopped = false;
881
876
  this.loaded = new Promise((resolve) => {
882
877
  this.resolveLoaded = resolve;
883
878
  });
879
+ this.firstReadEnded = new Promise((resolve) => {
880
+ this.resolveFirstReadEnded = resolve;
881
+ });
884
882
  }
885
883
  disabled() {
886
884
  return !this.enabled || simulationPlanEnvDisabled();
@@ -898,19 +896,21 @@ var SimulationPlan = class {
898
896
  "sim-plan-unreadable",
899
897
  "the sim plan response was not understood"
900
898
  );
901
- return;
899
+ } else {
900
+ this.markLoaded(parsed);
902
901
  }
903
- this.markLoaded(parsed);
902
+ this.endFirstRead();
904
903
  },
905
904
  (error) => {
906
905
  if (missingSimulationPlanEndpoint(error)) {
907
906
  this.markLoaded(/* @__PURE__ */ new Map());
908
- return;
907
+ } else {
908
+ this.scheduleRetry(
909
+ "sim-plan-unavailable",
910
+ `could not read the sim plan: ${error instanceof Error ? error.message : String(error)}`
911
+ );
909
912
  }
910
- this.scheduleRetry(
911
- "sim-plan-unavailable",
912
- `could not read the sim plan: ${error instanceof Error ? error.message : String(error)}`
913
- );
913
+ this.endFirstRead();
914
914
  }
915
915
  );
916
916
  }
@@ -920,11 +920,8 @@ var SimulationPlan = class {
920
920
  }
921
921
  this.contentOffByKey = parsed;
922
922
  this.policyRefresh.hold(SIMULATION_PLAN_REFRESH_MS);
923
- this.retryPending = false;
924
- this.clearRetryTimer();
925
923
  this.resolveLoaded?.();
926
924
  this.resolveLoaded = void 0;
927
- this.releaseHeld();
928
925
  }
929
926
  scheduleRetry(warnKey, reason) {
930
927
  if (this.stopped) {
@@ -934,39 +931,50 @@ var SimulationPlan = class {
934
931
  if (this.contentOffByKey !== void 0) {
935
932
  return;
936
933
  }
937
- this.retryPending = true;
938
934
  warnOnce(
939
935
  warnKey,
940
- `${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.`
936
+ `${reason}. Until a read succeeds, spans are sent without their inputs and outputs, except each trace's root span and spans recorded by a framework integration. The read is retried on the next span after ${SIMULATION_PLAN_RETRY_MS / 1e3}s.`
941
937
  );
942
- this.armRetry();
943
- }
944
- holdsWork() {
945
- return this.held.length > 0 || this.waitingForFirstLoad > 0;
946
938
  }
947
- armRetry() {
948
- if (this.stopped || !this.retryPending || this.retryTimer !== void 0 || !this.holdsWork()) {
949
- return;
939
+ endFirstRead() {
940
+ this.endRootWait();
941
+ if (!this.firstReadOver) {
942
+ this.firstReadOver = true;
943
+ this.resolveFirstReadEnded?.();
944
+ this.resolveFirstReadEnded = void 0;
950
945
  }
951
- const timer = setTimeout(() => {
952
- this.retryTimer = void 0;
953
- this.policyRefresh.releaseHold();
954
- this.refresh();
955
- }, SIMULATION_PLAN_RETRY_MS);
956
- unrefTimer(timer);
957
- this.retryTimer = timer;
946
+ this.releaseHeld();
958
947
  }
959
- clearRetryTimer() {
960
- if (this.retryTimer !== void 0) {
961
- clearTimeout(this.retryTimer);
962
- this.retryTimer = void 0;
948
+ endRootWait() {
949
+ this.rootWaitOver = true;
950
+ if (this.rootWaitTimer !== void 0) {
951
+ clearTimeout(this.rootWaitTimer);
952
+ this.rootWaitTimer = void 0;
963
953
  }
954
+ this.resolveRootWait?.();
955
+ this.resolveRootWait = void 0;
964
956
  }
965
- syncRetryTimer() {
966
- if (this.holdsWork()) {
967
- return;
957
+ waitForFirstRead() {
958
+ this.refresh();
959
+ if (this.rootWaitOver || this.disabled() || !this.holdingForFirstRead()) {
960
+ return void 0;
961
+ }
962
+ if (this.rootWait === void 0) {
963
+ this.rootWait = new Promise((resolve) => {
964
+ this.resolveRootWait = resolve;
965
+ });
966
+ this.rootWaitTimer = setTimeout(
967
+ () => this.endRootWait(),
968
+ SIMULATION_PLAN_READ_TIMEOUT_MS
969
+ );
968
970
  }
969
- this.clearRetryTimer();
971
+ return this.rootWait;
972
+ }
973
+ holdingForFirstRead() {
974
+ return this.contentOffByKey === void 0 && !this.firstReadOver && !this.stopped;
975
+ }
976
+ unavailableNow() {
977
+ return !this.disabled() && this.contentOffByKey === void 0 && this.firstReadOver;
970
978
  }
971
979
  firstLoad() {
972
980
  if (this.contentOffByKey !== void 0 || this.stopped || this.disabled()) {
@@ -976,19 +984,20 @@ var SimulationPlan = class {
976
984
  }
977
985
  send(payload, traceFunctionKey, submit) {
978
986
  this.refresh();
979
- if (this.stopped || this.disabled() || traceFunctionKey === void 0 || spanNameOf(payload) === void 0 || recordedByFramework(payload)) {
987
+ if (this.disabled() || traceFunctionKey === void 0 || spanNameOf(payload) === void 0 || recordedByFramework(payload)) {
980
988
  submit(payload);
981
989
  return;
982
990
  }
983
- if (this.contentOffByKey === void 0) {
984
- this.hold({ payload, traceFunctionKey, submit });
991
+ const entry = { payload, traceFunctionKey, submit };
992
+ if (this.holdingForFirstRead()) {
993
+ this.hold(entry);
985
994
  return;
986
995
  }
987
- this.submitEntry({ payload, traceFunctionKey, submit });
996
+ this.submitEntry(entry);
988
997
  }
989
998
  sendTrace(payload, submit) {
990
999
  this.refresh();
991
- if (this.stopped || this.disabled() || this.contentOffByKey !== void 0 || !this.holdsSpanOfTrace(traceIdOf(payload))) {
1000
+ if (this.disabled() || !this.holdingForFirstRead() || !this.holdsSpanOfTrace(traceIdOf(payload))) {
992
1001
  submit(payload);
993
1002
  return;
994
1003
  }
@@ -1004,17 +1013,34 @@ var SimulationPlan = class {
1004
1013
  }
1005
1014
  hold(entry) {
1006
1015
  this.held.push(entry);
1016
+ let overflowed = false;
1007
1017
  while (this.held.length > SIMULATION_PLAN_MAX_HELD) {
1008
- this.held.shift();
1009
- this.droppedWhileHolding += 1;
1018
+ const oldest = this.held.shift();
1019
+ this.submitEntry(oldest);
1020
+ overflowed = true;
1021
+ }
1022
+ if (overflowed) {
1023
+ warnOnce(
1024
+ "sim-plan-held-overflow",
1025
+ `more than ${SIMULATION_PLAN_MAX_HELD} records were waiting for the sim plan, so the oldest were sent without their inputs and outputs.`
1026
+ );
1027
+ }
1028
+ }
1029
+ payloadToSend(entry) {
1030
+ if (entry.traceFunctionKey === void 0) {
1031
+ return entry.payload;
1010
1032
  }
1011
- this.armRetry();
1033
+ if (this.contentOffByKey !== void 0) {
1034
+ return this.apply(entry.payload, entry.traceFunctionKey);
1035
+ }
1036
+ if (recordedByFramework(entry.payload) || isTraceRootSpan(entry.payload)) {
1037
+ return entry.payload;
1038
+ }
1039
+ return stripContent(entry.payload);
1012
1040
  }
1013
1041
  submitEntry(entry) {
1014
1042
  try {
1015
- entry.submit(
1016
- entry.traceFunctionKey === void 0 ? entry.payload : this.apply(entry.payload, entry.traceFunctionKey)
1017
- );
1043
+ entry.submit(this.payloadToSend(entry));
1018
1044
  } catch (error) {
1019
1045
  warnOnce(
1020
1046
  "sim-plan-held-span-dropped",
@@ -1025,62 +1051,38 @@ var SimulationPlan = class {
1025
1051
  releaseHeld() {
1026
1052
  const held = this.held;
1027
1053
  this.held = [];
1028
- this.syncRetryTimer();
1029
- this.warnDropped();
1030
1054
  for (const entry of held) {
1031
1055
  this.submitEntry(entry);
1032
1056
  }
1033
1057
  }
1034
- warnDropped() {
1035
- if (this.droppedWhileHolding === 0) {
1036
- return;
1037
- }
1038
- const dropped = this.droppedWhileHolding;
1039
- this.droppedWhileHolding = 0;
1040
- warnOnce(
1041
- "sim-plan-held-overflow",
1042
- `${dropped} record(s) were dropped while the sim plan was still loading; at most ${SIMULATION_PLAN_MAX_HELD} are held per client.`
1043
- );
1044
- }
1045
- warnNeverLoaded() {
1058
+ releaseHeldWithoutPlan() {
1046
1059
  if (this.held.length === 0) {
1047
1060
  return;
1048
1061
  }
1049
- warnOnce(
1050
- "sim-plan-never-loaded",
1051
- `${this.held.length} record(s) were not sent because the sim plan never loaded`
1052
- );
1062
+ if (this.contentOffByKey === void 0) {
1063
+ warnOnce(
1064
+ "sim-plan-not-loaded-at-release",
1065
+ `${this.held.length} record(s) were sent without their inputs and outputs because the sim plan had not loaded`
1066
+ );
1067
+ }
1068
+ this.releaseHeld();
1053
1069
  }
1054
1070
  async release(timeoutMs) {
1055
1071
  this.refresh();
1056
- if (this.holdsWork()) {
1057
- await this.waitForFirstLoad(timeoutMs);
1072
+ if (this.held.length > 0) {
1073
+ await this.waitForFirstReadEnd(timeoutMs);
1058
1074
  }
1059
- this.warnNeverLoaded();
1060
- this.warnDropped();
1075
+ this.releaseHeldWithoutPlan();
1061
1076
  }
1062
- waitForFirstLoad(timeoutMs) {
1063
- const firstLoad = this.firstLoad();
1064
- if (firstLoad === void 0) {
1077
+ waitForFirstReadEnd(timeoutMs) {
1078
+ if (this.firstReadOver) {
1065
1079
  return Promise.resolve();
1066
1080
  }
1067
- this.waitingForFirstLoad += 1;
1068
- this.armRetry();
1069
1081
  return new Promise((resolve) => {
1070
- let settled = false;
1071
- const finish = () => {
1072
- if (settled) {
1073
- return;
1074
- }
1075
- settled = true;
1076
- this.waitingForFirstLoad -= 1;
1077
- this.syncRetryTimer();
1078
- resolve();
1079
- };
1080
- const timer = setTimeout(finish, Math.max(timeoutMs, 0));
1081
- void firstLoad.then(() => {
1082
+ const timer = setTimeout(resolve, Math.max(timeoutMs, 0));
1083
+ void this.firstReadEnded.then(() => {
1082
1084
  clearTimeout(timer);
1083
- finish();
1085
+ resolve();
1084
1086
  });
1085
1087
  });
1086
1088
  }
@@ -1088,16 +1090,16 @@ var SimulationPlan = class {
1088
1090
  if (this.stopped) {
1089
1091
  return;
1090
1092
  }
1093
+ this.releaseHeldWithoutPlan();
1091
1094
  this.stopped = true;
1092
- this.retryPending = false;
1093
- this.clearRetryTimer();
1094
- this.warnNeverLoaded();
1095
- this.held = [];
1096
- this.warnDropped();
1095
+ this.endFirstRead();
1097
1096
  }
1098
1097
  contentOff(traceFunctionKey, spanName) {
1099
1098
  return this.contentOffByKey?.get(traceFunctionKey)?.has(spanName) === true;
1100
1099
  }
1100
+ contentOffNow(traceFunctionKey, spanName) {
1101
+ return !this.stopped && !this.disabled() && this.contentOff(traceFunctionKey, spanName);
1102
+ }
1101
1103
  apply(payload, traceFunctionKey) {
1102
1104
  if (recordedByFramework(payload)) {
1103
1105
  return payload;
@@ -1225,6 +1227,14 @@ var DeliveryError = class extends Error {
1225
1227
  }
1226
1228
  };
1227
1229
 
1230
+ // src/unrefTimer.ts
1231
+ function unrefTimer(timer) {
1232
+ const handle = timer;
1233
+ if (typeof handle.unref === "function") {
1234
+ handle.unref();
1235
+ }
1236
+ }
1237
+
1228
1238
  // src/otel.ts
1229
1239
  var OPERATION_ATTRIBUTE = "bitfab.operation";
1230
1240
  var PAYLOAD_ATTRIBUTE = "bitfab.payload";
@@ -1850,9 +1860,14 @@ var pendingTracePromises = /* @__PURE__ */ new Set();
1850
1860
  var liveHttpClients = /* @__PURE__ */ new Set();
1851
1861
  async function releaseHeldExternalSpans(timeoutMs) {
1852
1862
  const deadline = Date.now() + Math.max(timeoutMs, 0);
1863
+ let released = true;
1853
1864
  for (const client of [...liveHttpClients]) {
1854
- await client.releaseHeldExternalSpans?.(Math.max(0, deadline - Date.now()));
1865
+ const result = await client.releaseHeldExternalSpans?.(
1866
+ Math.max(0, deadline - Date.now())
1867
+ );
1868
+ released = result !== false && released;
1855
1869
  }
1870
+ return released;
1856
1871
  }
1857
1872
  function stopSimulationPlans() {
1858
1873
  for (const client of [...liveHttpClients]) {
@@ -1869,14 +1884,15 @@ function awaitOnExit(promise) {
1869
1884
  }
1870
1885
  async function flushTraces(timeoutMs = 5e3) {
1871
1886
  const deadline = Date.now() + Math.max(timeoutMs, 0);
1872
- await releaseHeldExternalSpans(planWaitSliceMs(timeoutMs));
1887
+ const released = await releaseHeldExternalSpans(planWaitSliceMs(timeoutMs));
1873
1888
  const requestsFlushed = await awaitPendingRequests(
1874
1889
  Math.max(0, deadline - Date.now())
1875
1890
  );
1891
+ const releasedAfterDeferred = await releaseHeldExternalSpans(0);
1876
1892
  const transportsFlushed = await flushTraceTransports(
1877
1893
  Math.max(0, deadline - Date.now())
1878
1894
  );
1879
- return requestsFlushed && transportsFlushed;
1895
+ return released && releasedAfterDeferred && requestsFlushed && transportsFlushed;
1880
1896
  }
1881
1897
  async function awaitPendingRequests(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS2) {
1882
1898
  await replayContextReady.catch(() => {
@@ -2261,13 +2277,17 @@ var HttpClient = class {
2261
2277
  */
2262
2278
  async settleDeferredWork(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS2) {
2263
2279
  const deadline = Date.now() + Math.max(timeoutMs, 0);
2264
- await this.releaseHeldExternalSpans?.(planWaitSliceMs(timeoutMs));
2280
+ const released = await this.releaseHeldExternalSpans?.(
2281
+ planWaitSliceMs(timeoutMs)
2282
+ );
2265
2283
  await replayContextReady.catch(() => {
2266
2284
  });
2267
- return waitForPromises(
2285
+ const settled = await waitForPromises(
2268
2286
  Array.from(this.deferredWork),
2269
2287
  Math.max(0, deadline - Date.now())
2270
2288
  );
2289
+ const releasedAfterDeferred = await this.releaseHeldExternalSpans?.(0);
2290
+ return released !== false && releasedAfterDeferred !== false && settled;
2271
2291
  }
2272
2292
  /**
2273
2293
  * Wait for spans queued by this client to be delivered, within one deadline.
@@ -2292,7 +2312,9 @@ var HttpClient = class {
2292
2312
  }
2293
2313
  const deadline = Date.now() + Math.max(timeoutMs, 0);
2294
2314
  this.closing = (async () => {
2295
- await this.releaseHeldExternalSpans?.(planWaitSliceMs(timeoutMs));
2315
+ const released = await this.releaseHeldExternalSpans?.(
2316
+ planWaitSliceMs(timeoutMs)
2317
+ );
2296
2318
  this.stopSimulationPlan?.();
2297
2319
  this.externalSpanTransform = void 0;
2298
2320
  this.externalTraceTransform = void 0;
@@ -2306,7 +2328,7 @@ var HttpClient = class {
2306
2328
  const transport = this.traceTransport;
2307
2329
  this.traceTransport = void 0;
2308
2330
  const shutdownOk = await transport?.shutdown(Math.max(0, deadline - Date.now())) ?? true;
2309
- return settled && shutdownOk;
2331
+ return released !== false && settled && shutdownOk;
2310
2332
  })();
2311
2333
  return this.closing;
2312
2334
  }
@@ -2799,8 +2821,12 @@ export {
2799
2821
  MAX_COMPRESSIBLE_SPAN_CARRIER_BYTES,
2800
2822
  warnOnce,
2801
2823
  serializePayloadBody,
2824
+ isFrameworkInstrumentation,
2802
2825
  makeSpanOrigin,
2826
+ recordedByFramework,
2803
2827
  ROOT_TRACE_FUNCTION_KEY_FIELD,
2828
+ CONTENT_OFF_KEY,
2829
+ traceIdOf,
2804
2830
  SimulationPlan,
2805
2831
  recordCallerTraceMetadata,
2806
2832
  callerTraceMetadata,
@@ -2811,4 +2837,4 @@ export {
2811
2837
  parseRetryAfterMs,
2812
2838
  HttpClient
2813
2839
  };
2814
- //# sourceMappingURL=chunk-YKOD4GWI.js.map
2840
+ //# sourceMappingURL=chunk-YE75OWXI.js.map