@blaxel/core 0.2.82-preview.145 → 0.2.82-preview.147

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 (43) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/common/h2fetch.js +93 -13
  3. package/dist/cjs/common/h2pool.js +109 -14
  4. package/dist/cjs/common/lazyInit.js +1 -1
  5. package/dist/cjs/common/settings.js +11 -2
  6. package/dist/cjs/sandbox/action.js +12 -8
  7. package/dist/cjs/sandbox/interpreter.js +6 -3
  8. package/dist/cjs/sandbox/sandbox.js +22 -11
  9. package/dist/cjs/types/common/h2fetch.d.ts +6 -6
  10. package/dist/cjs/types/common/h2pool.d.ts +20 -0
  11. package/dist/cjs/types/common/settings.d.ts +2 -0
  12. package/dist/cjs/types/sandbox/action.d.ts +1 -0
  13. package/dist/cjs/types/sandbox/sandbox.d.ts +4 -1
  14. package/dist/cjs/types/sandbox/types.d.ts +1 -0
  15. package/dist/cjs-browser/.tsbuildinfo +1 -1
  16. package/dist/cjs-browser/common/h2fetch.js +1 -0
  17. package/dist/cjs-browser/common/lazyInit.js +1 -1
  18. package/dist/cjs-browser/common/settings.js +11 -2
  19. package/dist/cjs-browser/sandbox/action.js +12 -8
  20. package/dist/cjs-browser/sandbox/interpreter.js +6 -3
  21. package/dist/cjs-browser/sandbox/sandbox.js +22 -11
  22. package/dist/cjs-browser/types/common/h2fetch.d.ts +6 -6
  23. package/dist/cjs-browser/types/common/h2pool.d.ts +20 -0
  24. package/dist/cjs-browser/types/common/settings.d.ts +2 -0
  25. package/dist/cjs-browser/types/sandbox/action.d.ts +1 -0
  26. package/dist/cjs-browser/types/sandbox/sandbox.d.ts +4 -1
  27. package/dist/cjs-browser/types/sandbox/types.d.ts +1 -0
  28. package/dist/esm/.tsbuildinfo +1 -1
  29. package/dist/esm/common/h2fetch.js +92 -13
  30. package/dist/esm/common/h2pool.js +109 -14
  31. package/dist/esm/common/lazyInit.js +1 -1
  32. package/dist/esm/common/settings.js +11 -2
  33. package/dist/esm/sandbox/action.js +13 -9
  34. package/dist/esm/sandbox/interpreter.js +7 -4
  35. package/dist/esm/sandbox/sandbox.js +22 -11
  36. package/dist/esm-browser/.tsbuildinfo +1 -1
  37. package/dist/esm-browser/common/h2fetch.js +1 -0
  38. package/dist/esm-browser/common/lazyInit.js +1 -1
  39. package/dist/esm-browser/common/settings.js +11 -2
  40. package/dist/esm-browser/sandbox/action.js +13 -9
  41. package/dist/esm-browser/sandbox/interpreter.js +7 -4
  42. package/dist/esm-browser/sandbox/sandbox.js +22 -11
  43. package/package.json +1 -1
@@ -2,3 +2,4 @@
2
2
  export function createH2Fetch(session) { return (input) => globalThis.fetch(input); }
3
3
  export function createPoolBackedH2Fetch(pool, domain) { return (input) => globalThis.fetch(input); }
4
4
  export function h2RequestDirect(session, url, init) { return globalThis.fetch(url, init); }
5
+ export function h2RequestDirectFromPool(pool, domain, url, init) { return globalThis.fetch(url, init); }
@@ -41,7 +41,7 @@ export function ensureAutoloaded() {
41
41
  const isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
42
42
  /* eslint-disable */
43
43
  const isBrowser = typeof globalThis !== "undefined" && globalThis?.window !== undefined;
44
- if (isNode && !isBrowser) {
44
+ if (isNode && !isBrowser && !settings.disableH2) {
45
45
  try {
46
46
  // Pre-warm edge H2 for the configured region so the first
47
47
  // SandboxInstance.create() gets an instant session via the pool.
@@ -5,8 +5,8 @@ import { authentication } from "../authentication/index.js";
5
5
  import { env } from "../common/env.js";
6
6
  import { fs, os, path } from "../common/node.js";
7
7
  // Build info - these placeholders are replaced at build time by build:replace-imports
8
- const BUILD_VERSION = "0.2.82-preview.145";
9
- const BUILD_COMMIT = "b6e081ff4ce9c6fee387b08e280bdfe804f52370";
8
+ const BUILD_VERSION = "0.2.82-preview.147";
9
+ const BUILD_COMMIT = "4d2b3531bdb9d8a065f6d83822343840ae0b8d65";
10
10
  const BUILD_SENTRY_DSN = "https://fd5e60e1c9820e1eef5ccebb84a07127@o4508714045276160.ingest.us.sentry.io/4510465864564736";
11
11
  const BLAXEL_API_VERSION = "2026-04-16";
12
12
  // Cache for config.yaml tracking value
@@ -212,6 +212,15 @@ class Settings {
212
212
  get region() {
213
213
  return env.BL_REGION || undefined;
214
214
  }
215
+ get disableH2() {
216
+ if (typeof this.config.disableH2 === "boolean") {
217
+ return this.config.disableH2;
218
+ }
219
+ const value = env.BL_DISABLE_H2;
220
+ if (!value)
221
+ return false;
222
+ return ["1", "true", "yes", "on"].includes(value.toLowerCase());
223
+ }
215
224
  async authenticate() {
216
225
  await this.credentials.authenticate();
217
226
  }
@@ -1,7 +1,8 @@
1
1
  import { createClient } from "@hey-api/client-fetch";
2
2
  import { interceptors } from "../client/interceptors.js";
3
3
  import { responseInterceptors } from "../client/responseInterceptor.js";
4
- import { createH2Fetch, h2RequestDirect } from "../common/h2fetch.js";
4
+ import { createPoolBackedH2Fetch, h2RequestDirectFromPool } from "../common/h2fetch.js";
5
+ import { h2Pool } from "../common/h2pool.js";
5
6
  import { getForcedUrl, getGlobalUniqueHash } from "../common/internal.js";
6
7
  import { settings } from "../common/settings.js";
7
8
  import { client as defaultClient } from "./client/client.gen.js";
@@ -32,6 +33,7 @@ export class ResponseError extends Error {
32
33
  export class SandboxAction {
33
34
  sandbox;
34
35
  _h2Client = null;
36
+ _h2ClientDomain = null;
35
37
  constructor(sandbox) {
36
38
  this.sandbox = sandbox;
37
39
  }
@@ -58,12 +60,13 @@ export class SandboxAction {
58
60
  headers: this.sandbox.headers,
59
61
  });
60
62
  }
61
- const session = this.sandbox.h2Session;
62
- if (session && !session.closed && !session.destroyed) {
63
- if (!this._h2Client) {
63
+ const h2Domain = this.sandbox.h2Domain;
64
+ if (h2Domain) {
65
+ if (!this._h2Client || this._h2ClientDomain !== h2Domain) {
64
66
  this._h2Client = createClient({
65
- fetch: createH2Fetch(session),
67
+ fetch: createPoolBackedH2Fetch(h2Pool, h2Domain),
66
68
  });
69
+ this._h2ClientDomain = h2Domain;
67
70
  for (const interceptor of interceptors) {
68
71
  // @ts-expect-error - Interceptor is not typed
69
72
  this._h2Client.interceptors.request.use(interceptor);
@@ -74,8 +77,9 @@ export class SandboxAction {
74
77
  }
75
78
  return this._h2Client;
76
79
  }
77
- // Invalidate cached H2 client when session is no longer usable
80
+ // Invalidate cached H2 client when the sandbox no longer has an H2 domain.
78
81
  this._h2Client = null;
82
+ this._h2ClientDomain = null;
79
83
  return defaultClient;
80
84
  }
81
85
  /**
@@ -83,9 +87,9 @@ export class SandboxAction {
83
87
  * globalThis.fetch. Uses a direct H2 path that avoids Request allocation.
84
88
  */
85
89
  h2Fetch(input, init) {
86
- const session = this.sandbox.h2Session;
87
- if (session && !session.closed && !session.destroyed) {
88
- return h2RequestDirect(session, input.toString(), init);
90
+ const h2Domain = this.sandbox.h2Domain;
91
+ if (h2Domain) {
92
+ return h2RequestDirectFromPool(h2Pool, h2Domain, input.toString(), init);
89
93
  }
90
94
  return globalThis.fetch(input, init);
91
95
  }
@@ -1,4 +1,5 @@
1
- import { h2RequestDirect } from "../common/h2fetch.js";
1
+ import { h2RequestDirectFromPool } from "../common/h2fetch.js";
2
+ import { h2Pool } from "../common/h2pool.js";
2
3
  import { logger } from "../common/logger.js";
3
4
  import { settings } from "../common/settings.js";
4
5
  import { SandboxInstance } from "./sandbox.js";
@@ -25,6 +26,7 @@ export class CodeInterpreter extends SandboxInstance {
25
26
  status: base.status,
26
27
  events: base.events,
27
28
  h2Session: base.h2Session,
29
+ h2Domain: base.h2Domain,
28
30
  };
29
31
  return new CodeInterpreter(config);
30
32
  }
@@ -69,6 +71,7 @@ export class CodeInterpreter extends SandboxInstance {
69
71
  status: baseInstance.status,
70
72
  events: baseInstance.events,
71
73
  h2Session: baseInstance.h2Session,
74
+ h2Domain: baseInstance.h2Domain,
72
75
  };
73
76
  // Preserve forceUrl, headers, and params from input if provided
74
77
  if (sandbox && typeof sandbox === "object" && !Array.isArray(sandbox)) {
@@ -91,9 +94,9 @@ export class CodeInterpreter extends SandboxInstance {
91
94
  return this.process.url;
92
95
  }
93
96
  _fetch(input, init) {
94
- const session = this._sandboxConfig.h2Session;
95
- if (session && !session.closed && !session.destroyed) {
96
- return h2RequestDirect(session, input.toString(), init);
97
+ const h2Domain = this._sandboxConfig.h2Domain;
98
+ if (h2Domain) {
99
+ return h2RequestDirectFromPool(h2Pool, h2Domain, input.toString(), init);
97
100
  }
98
101
  return globalThis.fetch(input, init);
99
102
  }
@@ -21,7 +21,6 @@ export class SandboxInstance {
21
21
  codegen;
22
22
  system;
23
23
  drives;
24
- /* eslint-disable @typescript-eslint/no-explicit-any */
25
24
  h2Session;
26
25
  constructor(sandbox) {
27
26
  this.sandbox = sandbox;
@@ -50,27 +49,35 @@ export class SandboxInstance {
50
49
  get lastUsedAt() {
51
50
  return this.sandbox.lastUsedAt;
52
51
  }
52
+ get h2Domain() {
53
+ return this.sandbox.h2Domain ?? null;
54
+ }
53
55
  /**
54
56
  * Warm and attach an H2 session based on the sandbox's region.
55
57
  * Shared by create(), get(), list(), and update helpers.
56
58
  */
57
59
  static async attachH2Session(instance) {
58
- const region = instance.spec?.region;
59
- if (!region)
60
+ const edgeDomain = SandboxInstance.edgeDomainForRegion(instance.spec?.region);
61
+ if (!edgeDomain || settings.disableH2)
60
62
  return instance;
61
- const edgeSuffix = settings.env === "prod" ? "bl.run" : "runv2.blaxel.dev";
62
- const edgeDomain = `any.${region}.${edgeSuffix}`;
63
63
  try {
64
64
  const { h2Pool } = await import("../common/h2pool.js");
65
65
  const h2Session = await h2Pool.get(edgeDomain);
66
66
  instance.h2Session = h2Session;
67
67
  instance.sandbox.h2Session = h2Session;
68
+ instance.sandbox.h2Domain = edgeDomain;
68
69
  }
69
70
  catch {
70
71
  // H2 warming is best-effort; fall back to regular fetch
71
72
  }
72
73
  return instance;
73
74
  }
75
+ static edgeDomainForRegion(region) {
76
+ if (!region)
77
+ return null;
78
+ const edgeSuffix = settings.env === "prod" ? "bl.run" : "runv2.blaxel.dev";
79
+ return `any.${region}.${edgeSuffix}`;
80
+ }
74
81
  get expiresIn() {
75
82
  return this.sandbox.expiresIn;
76
83
  }
@@ -165,10 +172,9 @@ export class SandboxInstance {
165
172
  }
166
173
  sandbox.spec.runtime.image = sandbox.spec.runtime.image || defaultImage;
167
174
  sandbox.spec.runtime.memory = sandbox.spec.runtime.memory || defaultMemory;
168
- const edgeSuffix = settings.env === "prod" ? "bl.run" : "runv2.blaxel.dev";
169
- const edgeDomain = sandbox.spec?.region ? `any.${sandbox.spec.region}.${edgeSuffix}` : null;
175
+ const edgeDomain = SandboxInstance.edgeDomainForRegion(sandbox.spec?.region);
170
176
  // Kick off warming so h2Pool.get() can join it during the API call
171
- if (edgeDomain) {
177
+ if (edgeDomain && !settings.disableH2) {
172
178
  import("../common/h2pool.js").then(({ h2Pool }) => h2Pool.warm(edgeDomain)).catch(() => { });
173
179
  }
174
180
  const [{ data }, h2Session] = await Promise.all([
@@ -176,10 +182,10 @@ export class SandboxInstance {
176
182
  body: sandbox,
177
183
  throwOnError: true,
178
184
  }),
179
- edgeDomain ? import("../common/h2pool.js").then(({ h2Pool }) => h2Pool.get(edgeDomain)).catch(() => null) : Promise.resolve(null),
185
+ edgeDomain && !settings.disableH2 ? import("../common/h2pool.js").then(({ h2Pool }) => h2Pool.get(edgeDomain)).catch(() => null) : Promise.resolve(null),
180
186
  ]);
181
187
  // Inject the H2 session into the config so subsystems can use it
182
- const config = { ...data, h2Session };
188
+ const config = { ...data, h2Session, h2Domain: settings.disableH2 ? null : edgeDomain };
183
189
  const instance = new SandboxInstance(config);
184
190
  instance.h2Session = h2Session;
185
191
  // Note: H2 session already attached via Promise.all above, no need for attachH2Session()
@@ -188,7 +194,10 @@ export class SandboxInstance {
188
194
  try {
189
195
  await instance.fs.ls('/');
190
196
  }
191
- catch { }
197
+ catch (err) {
198
+ await SandboxInstance.delete(instance.metadata.name).catch(() => { });
199
+ throw err;
200
+ }
192
201
  }
193
202
  return instance;
194
203
  }
@@ -219,6 +228,8 @@ export class SandboxInstance {
219
228
  async delete() {
220
229
  // Don't close the H2 session — it's shared via h2Pool
221
230
  this.h2Session = null;
231
+ this.sandbox.h2Session = null;
232
+ this.sandbox.h2Domain = null;
222
233
  return await SandboxInstance.delete(this.metadata.name);
223
234
  }
224
235
  static async updateMetadata(sandboxName, metadata) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blaxel/core",
3
- "version": "0.2.82-preview.145",
3
+ "version": "0.2.82-preview.147",
4
4
  "description": "Blaxel Core SDK for TypeScript",
5
5
  "license": "MIT",
6
6
  "author": "Blaxel, INC (https://blaxel.ai)",