@blaxel/core 0.3.5 → 0.3.6

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.
@@ -11,6 +11,7 @@ const credentials_js_1 = require("../authentication/credentials.js");
11
11
  const index_js_1 = require("../authentication/index.js");
12
12
  const env_js_1 = require("../common/env.js");
13
13
  const errors_js_1 = require("../common/errors.js");
14
+ const logger_js_1 = require("../common/logger.js");
14
15
  const node_js_1 = require("../common/node.js");
15
16
  /**
16
17
  * Build an actionable "credentials missing" message naming exactly which piece
@@ -28,10 +29,23 @@ function missingCredentialsMessage() {
28
29
  return "No Blaxel credentials found. Set the BL_API_KEY and BL_WORKSPACE environment variables, or run `bl login`.";
29
30
  }
30
31
  // Build info - these placeholders are replaced at build time by build:replace-imports
31
- const BUILD_VERSION = "0.3.5";
32
- const BUILD_COMMIT = "2d81ed89ffd7cfef222c23b636999cee8cc91160";
32
+ const BUILD_VERSION = "0.3.6";
33
+ const BUILD_COMMIT = "3189881cfb78a38e368844ba3fc867f83933cade";
33
34
  const BUILD_SENTRY_DSN = "https://fd5e60e1c9820e1eef5ccebb84a07127@o4508714045276160.ingest.us.sentry.io/4510465864564736";
34
35
  const BLAXEL_API_VERSION = "2026-04-28";
36
+ // Bun < 1.3.11 never sends connection-level WINDOW_UPDATE: the pooled h2
37
+ // session freezes after exactly 65535 cumulative body bytes and every request
38
+ // on it hangs until the edge resets the streams (~330s).
39
+ // Fixed in Bun 1.3.11: https://bun.com/blog/bun-v1.3.11
40
+ function isBrokenBunH2() {
41
+ const v = globalThis.process?.versions?.bun;
42
+ if (!v)
43
+ return false;
44
+ const [maj = 0, min = 0, patch = 0] = v.split("-")[0].split(".").map(Number);
45
+ return maj < 1 || (maj === 1 && (min < 3 || (min === 3 && patch < 11)));
46
+ }
47
+ // Warn at most once when H2 is force-disabled on a broken Bun runtime.
48
+ let brokenBunH2Warned = false;
35
49
  // Cache for config.yaml tracking value
36
50
  let configTrackingValue = null;
37
51
  let configTrackingLoaded = false;
@@ -237,6 +251,19 @@ class Settings {
237
251
  return env_js_1.env.BL_REGION || undefined;
238
252
  }
239
253
  get disableH2() {
254
+ // Broken Bun versions hang on the pooled H2 session; force H2 off there
255
+ // regardless of config/env and warn once so the choice is visible.
256
+ if (isBrokenBunH2()) {
257
+ if (!brokenBunH2Warned) {
258
+ brokenBunH2Warned = true;
259
+ logger_js_1.logger.warn(`Detected Bun ${globalThis.process?.versions?.bun} which never sends ` +
260
+ `connection-level HTTP/2 WINDOW_UPDATE: the pooled H2 session freezes ` +
261
+ `after 65535 cumulative body bytes and requests hang until the edge ` +
262
+ `resets the streams (~330s). Disabling H2 (fixed in Bun 1.3.11: ` +
263
+ `https://bun.com/blog/bun-v1.3.11).`);
264
+ }
265
+ return true;
266
+ }
240
267
  if (typeof this.config.disableH2 === "boolean") {
241
268
  return this.config.disableH2;
242
269
  }
@@ -244,7 +271,7 @@ class Settings {
244
271
  if (value) {
245
272
  return ["1", "true", "yes", "on"].includes(value.toLowerCase());
246
273
  }
247
- return true;
274
+ return false;
248
275
  }
249
276
  // Control-plane-only escape hatch: disables the control-plane H2 wrapper
250
277
  // without affecting data-plane (edge) H2. `disableH2` is the global override
@@ -68,15 +68,22 @@ const env_js_1 = require("./env.js");
68
68
  const { settings } = await Promise.resolve().then(() => __importStar(require('./settings.js')));
69
69
  delete settings.config.disableH2;
70
70
  });
71
- (0, vitest_1.it)('disables H2 by default', async () => {
71
+ const onBrokenBun = (() => {
72
+ const v = globalThis.process?.versions?.bun;
73
+ if (!v)
74
+ return false;
75
+ const [maj = 0, min = 0, patch = 0] = v.split('.').map(Number);
76
+ return maj < 1 || (maj === 1 && (min < 3 || (min === 3 && patch < 11)));
77
+ })();
78
+ vitest_1.it.skipIf(onBrokenBun)('enables H2 by default', async () => {
72
79
  delete env_js_1.env.BL_DISABLE_H2;
73
80
  const { settings } = await Promise.resolve().then(() => __importStar(require('./settings.js')));
74
81
  delete settings.config.disableH2;
75
- (0, vitest_1.expect)(settings.disableH2).toBe(true);
82
+ (0, vitest_1.expect)(settings.disableH2).toBe(false);
76
83
  });
77
- (0, vitest_1.it)('allows H2 to be explicitly enabled', async () => {
84
+ vitest_1.it.skipIf(onBrokenBun)('allows H2 to be explicitly disabled', async () => {
78
85
  const { settings } = await Promise.resolve().then(() => __importStar(require('./settings.js')));
79
- settings.config.disableH2 = false;
80
- (0, vitest_1.expect)(settings.disableH2).toBe(false);
86
+ settings.config.disableH2 = true;
87
+ (0, vitest_1.expect)(settings.disableH2).toBe(true);
81
88
  });
82
89
  });
@@ -12,8 +12,10 @@ export type Config = {
12
12
  apikey?: string;
13
13
  workspace?: string;
14
14
  /**
15
- * Disables the SDK-managed HTTP/2 transport. Defaults to `true`; set this to
16
- * `false` (or `BL_DISABLE_H2=0`) to opt back into H2.
15
+ * Disables the SDK-managed HTTP/2 transport. Defaults to `false` (H2 on);
16
+ * set this to `true` (or `BL_DISABLE_H2=1`) to opt out of H2. Note that H2 is
17
+ * always force-disabled on Bun < 1.3.11, which has a broken H2 flow-control
18
+ * implementation, regardless of this setting.
17
19
  */
18
20
  disableH2?: boolean;
19
21
  /**