@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.
@@ -5,6 +5,7 @@ import { MissingCredentials } from "../authentication/credentials.js";
5
5
  import { authentication } from "../authentication/index.js";
6
6
  import { env } from "../common/env.js";
7
7
  import { CredentialsError } from "../common/errors.js";
8
+ import { logger } from "../common/logger.js";
8
9
  import { fs, os, path } from "../common/node.js";
9
10
  /**
10
11
  * Build an actionable "credentials missing" message naming exactly which piece
@@ -22,10 +23,23 @@ function missingCredentialsMessage() {
22
23
  return "No Blaxel credentials found. Set the BL_API_KEY and BL_WORKSPACE environment variables, or run `bl login`.";
23
24
  }
24
25
  // Build info - these placeholders are replaced at build time by build:replace-imports
25
- const BUILD_VERSION = "0.3.5";
26
- const BUILD_COMMIT = "2d81ed89ffd7cfef222c23b636999cee8cc91160";
26
+ const BUILD_VERSION = "0.3.6";
27
+ const BUILD_COMMIT = "3189881cfb78a38e368844ba3fc867f83933cade";
27
28
  const BUILD_SENTRY_DSN = "https://fd5e60e1c9820e1eef5ccebb84a07127@o4508714045276160.ingest.us.sentry.io/4510465864564736";
28
29
  const BLAXEL_API_VERSION = "2026-04-28";
30
+ // Bun < 1.3.11 never sends connection-level WINDOW_UPDATE: the pooled h2
31
+ // session freezes after exactly 65535 cumulative body bytes and every request
32
+ // on it hangs until the edge resets the streams (~330s).
33
+ // Fixed in Bun 1.3.11: https://bun.com/blog/bun-v1.3.11
34
+ function isBrokenBunH2() {
35
+ const v = globalThis.process?.versions?.bun;
36
+ if (!v)
37
+ return false;
38
+ const [maj = 0, min = 0, patch = 0] = v.split("-")[0].split(".").map(Number);
39
+ return maj < 1 || (maj === 1 && (min < 3 || (min === 3 && patch < 11)));
40
+ }
41
+ // Warn at most once when H2 is force-disabled on a broken Bun runtime.
42
+ let brokenBunH2Warned = false;
29
43
  // Cache for config.yaml tracking value
30
44
  let configTrackingValue = null;
31
45
  let configTrackingLoaded = false;
@@ -231,6 +245,19 @@ class Settings {
231
245
  return env.BL_REGION || undefined;
232
246
  }
233
247
  get disableH2() {
248
+ // Broken Bun versions hang on the pooled H2 session; force H2 off there
249
+ // regardless of config/env and warn once so the choice is visible.
250
+ if (isBrokenBunH2()) {
251
+ if (!brokenBunH2Warned) {
252
+ brokenBunH2Warned = true;
253
+ logger.warn(`Detected Bun ${globalThis.process?.versions?.bun} which never sends ` +
254
+ `connection-level HTTP/2 WINDOW_UPDATE: the pooled H2 session freezes ` +
255
+ `after 65535 cumulative body bytes and requests hang until the edge ` +
256
+ `resets the streams (~330s). Disabling H2 (fixed in Bun 1.3.11: ` +
257
+ `https://bun.com/blog/bun-v1.3.11).`);
258
+ }
259
+ return true;
260
+ }
234
261
  if (typeof this.config.disableH2 === "boolean") {
235
262
  return this.config.disableH2;
236
263
  }
@@ -238,7 +265,7 @@ class Settings {
238
265
  if (value) {
239
266
  return ["1", "true", "yes", "on"].includes(value.toLowerCase());
240
267
  }
241
- return true;
268
+ return false;
242
269
  }
243
270
  // Control-plane-only escape hatch: disables the control-plane H2 wrapper
244
271
  // without affecting data-plane (edge) H2. `disableH2` is the global override
@@ -33,15 +33,22 @@ describe('Settings.disableH2', () => {
33
33
  const { settings } = await import('./settings.js');
34
34
  delete settings.config.disableH2;
35
35
  });
36
- it('disables H2 by default', async () => {
36
+ const onBrokenBun = (() => {
37
+ const v = globalThis.process?.versions?.bun;
38
+ if (!v)
39
+ return false;
40
+ const [maj = 0, min = 0, patch = 0] = v.split('.').map(Number);
41
+ return maj < 1 || (maj === 1 && (min < 3 || (min === 3 && patch < 11)));
42
+ })();
43
+ it.skipIf(onBrokenBun)('enables H2 by default', async () => {
37
44
  delete env.BL_DISABLE_H2;
38
45
  const { settings } = await import('./settings.js');
39
46
  delete settings.config.disableH2;
40
- expect(settings.disableH2).toBe(true);
47
+ expect(settings.disableH2).toBe(false);
41
48
  });
42
- it('allows H2 to be explicitly enabled', async () => {
49
+ it.skipIf(onBrokenBun)('allows H2 to be explicitly disabled', async () => {
43
50
  const { settings } = await import('./settings.js');
44
- settings.config.disableH2 = false;
45
- expect(settings.disableH2).toBe(false);
51
+ settings.config.disableH2 = true;
52
+ expect(settings.disableH2).toBe(true);
46
53
  });
47
54
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blaxel/core",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "description": "Blaxel Core SDK for TypeScript",
5
5
  "license": "MIT",
6
6
  "author": "Blaxel, INC (https://blaxel.ai)",