@blaxel/core 0.2.89 → 0.2.90-preview.182
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/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/common/autoload.js +3 -0
- package/dist/cjs/common/controlPlaneFetch.js +57 -0
- package/dist/cjs/common/lazyInit.js +5 -4
- package/dist/cjs/common/settings.js +27 -2
- package/dist/cjs/types/common/controlPlaneFetch.d.ts +4 -0
- package/dist/cjs/types/common/settings.d.ts +18 -0
- package/dist/cjs-browser/.tsbuildinfo +1 -1
- package/dist/cjs-browser/common/autoload.js +3 -0
- package/dist/cjs-browser/common/controlPlaneFetch.js +57 -0
- package/dist/cjs-browser/common/lazyInit.js +5 -4
- package/dist/cjs-browser/common/settings.js +27 -2
- package/dist/cjs-browser/types/common/controlPlaneFetch.d.ts +4 -0
- package/dist/cjs-browser/types/common/settings.d.ts +18 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/common/autoload.js +3 -0
- package/dist/esm/common/controlPlaneFetch.js +51 -0
- package/dist/esm/common/lazyInit.js +5 -4
- package/dist/esm/common/settings.js +27 -2
- package/dist/esm-browser/.tsbuildinfo +1 -1
- package/dist/esm-browser/common/autoload.js +3 -0
- package/dist/esm-browser/common/controlPlaneFetch.js +51 -0
- package/dist/esm-browser/common/lazyInit.js +5 -4
- package/dist/esm-browser/common/settings.js +27 -2
- package/package.json +1 -1
|
@@ -41,11 +41,13 @@ const client_gen_js_1 = require("../client/client.gen.js");
|
|
|
41
41
|
const interceptors_js_1 = require("../client/interceptors.js");
|
|
42
42
|
const responseInterceptor_js_1 = require("../client/responseInterceptor.js");
|
|
43
43
|
const client_gen_js_2 = require("../sandbox/client/client.gen.js");
|
|
44
|
+
const controlPlaneFetch_js_1 = require("./controlPlaneFetch.js");
|
|
44
45
|
const settings_js_1 = require("./settings.js");
|
|
45
46
|
var lazyInit_js_1 = require("./lazyInit.js");
|
|
46
47
|
Object.defineProperty(exports, "ensureAutoloaded", { enumerable: true, get: function () { return lazyInit_js_1.ensureAutoloaded; } });
|
|
47
48
|
client_gen_js_1.client.setConfig({
|
|
48
49
|
baseUrl: settings_js_1.settings.baseUrl,
|
|
50
|
+
fetch: controlPlaneFetch_js_1.controlPlaneFetch,
|
|
49
51
|
});
|
|
50
52
|
// Register request interceptors
|
|
51
53
|
for (const interceptor of interceptors_js_1.interceptors) {
|
|
@@ -90,6 +92,7 @@ function initialize(config) {
|
|
|
90
92
|
settings_js_1.settings.setConfig(config);
|
|
91
93
|
client_gen_js_1.client.setConfig({
|
|
92
94
|
baseUrl: settings_js_1.settings.baseUrl,
|
|
95
|
+
fetch: controlPlaneFetch_js_1.controlPlaneFetch,
|
|
93
96
|
});
|
|
94
97
|
client_gen_js_2.client.setConfig({
|
|
95
98
|
baseUrl: settings_js_1.settings.baseUrl,
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.nativeFetchSupportsH2 = void 0;
|
|
4
|
+
exports.undiciSupportsNativeH2 = undiciSupportsNativeH2;
|
|
5
|
+
exports.shouldUseControlPlaneH2 = shouldUseControlPlaneH2;
|
|
6
|
+
exports.controlPlaneFetch = controlPlaneFetch;
|
|
7
|
+
const h2fetch_js_1 = require("./h2fetch.js");
|
|
8
|
+
const h2pool_js_1 = require("./h2pool.js");
|
|
9
|
+
const settings_js_1 = require("./settings.js");
|
|
10
|
+
const h2FetchByHost = new Map();
|
|
11
|
+
// Node's global fetch dispatcher only negotiates HTTP/2 by default starting
|
|
12
|
+
// with undici 8 (Node 26+); undici 7 (Node 24) and undici 6 (Node 22) still
|
|
13
|
+
// ALPN to HTTP/1.1 for fetch, verified empirically against api.blaxel.ai. On
|
|
14
|
+
// undici >= 8 the pooled wrapper is redundant, so we prefer the native path.
|
|
15
|
+
function undiciSupportsNativeH2(undiciVersion) {
|
|
16
|
+
const major = Number(undiciVersion?.split(".")[0] ?? 0);
|
|
17
|
+
return major >= 8;
|
|
18
|
+
}
|
|
19
|
+
// `process`/`process.versions` is absent on Cloudflare Workers and other
|
|
20
|
+
// non-Node runtimes, and `process.versions.undici` is undefined on Bun/Deno;
|
|
21
|
+
// all of those resolve to `false` and keep the wrapper as the fallback.
|
|
22
|
+
exports.nativeFetchSupportsH2 = typeof process !== "undefined" && undiciSupportsNativeH2(process.versions?.undici);
|
|
23
|
+
function shouldUseControlPlaneH2(url, h2Disabled, proxyConfigured = false, nativeH2 = false, forceWrapper = false) {
|
|
24
|
+
if (h2Disabled || proxyConfigured)
|
|
25
|
+
return false;
|
|
26
|
+
if (url.protocol !== "https:")
|
|
27
|
+
return false;
|
|
28
|
+
// Token refresh is sequential and unauthenticated; it cannot contribute to
|
|
29
|
+
// the create burst TLS storm, and device-mode refresh currently relies on the
|
|
30
|
+
// native fetch path.
|
|
31
|
+
if (url.pathname.endsWith("/oauth/token"))
|
|
32
|
+
return false;
|
|
33
|
+
if (!(url.hostname.endsWith("blaxel.ai") || url.hostname.endsWith("blaxel.dev"))) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
// Native fetch already negotiates HTTP/2: skip the redundant wrapper unless
|
|
37
|
+
// explicitly forced (e.g. to exercise the pooled path on a modern runtime).
|
|
38
|
+
if (nativeH2 && !forceWrapper)
|
|
39
|
+
return false;
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
function controlPlaneFetch(input) {
|
|
43
|
+
const url = new URL(input.url);
|
|
44
|
+
const proxyConfigured = Boolean(settings_js_1.settings.config.proxy);
|
|
45
|
+
// Global disableH2 still wins; disableControlPlaneH2 opts out of just the
|
|
46
|
+
// control-plane wrapper while leaving data-plane H2 in place.
|
|
47
|
+
const h2Disabled = settings_js_1.settings.disableH2 || settings_js_1.settings.disableControlPlaneH2;
|
|
48
|
+
if (!shouldUseControlPlaneH2(url, h2Disabled, proxyConfigured, exports.nativeFetchSupportsH2, settings_js_1.settings.forceControlPlaneH2)) {
|
|
49
|
+
return globalThis.fetch(input);
|
|
50
|
+
}
|
|
51
|
+
let h2Fetch = h2FetchByHost.get(url.hostname);
|
|
52
|
+
if (!h2Fetch) {
|
|
53
|
+
h2Fetch = (0, h2fetch_js_1.createPoolBackedH2Fetch)(h2pool_js_1.h2Pool, url.hostname);
|
|
54
|
+
h2FetchByHost.set(url.hostname, h2Fetch);
|
|
55
|
+
}
|
|
56
|
+
return h2Fetch(input);
|
|
57
|
+
}
|
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.ensureAutoloaded = ensureAutoloaded;
|
|
37
37
|
const client_gen_js_1 = require("../client/client.gen.js");
|
|
38
38
|
const client_gen_js_2 = require("../sandbox/client/client.gen.js");
|
|
39
|
+
const controlPlaneFetch_js_1 = require("./controlPlaneFetch.js");
|
|
39
40
|
const sentry_js_1 = require("./sentry.js");
|
|
40
41
|
const settings_js_1 = require("./settings.js");
|
|
41
42
|
let autoloaded = false;
|
|
@@ -69,7 +70,7 @@ function ensureAutoloaded() {
|
|
|
69
70
|
// Keep the clients' baseUrl in sync with the now-resolved env. Without
|
|
70
71
|
// this, the module-load `client.setConfig({ baseUrl })` would be stuck on
|
|
71
72
|
// the prod default for users who rely on `config.yaml` (no env vars).
|
|
72
|
-
client_gen_js_1.client.setConfig({ baseUrl: settings_js_1.settings.baseUrl });
|
|
73
|
+
client_gen_js_1.client.setConfig({ baseUrl: settings_js_1.settings.baseUrl, fetch: controlPlaneFetch_js_1.controlPlaneFetch });
|
|
73
74
|
client_gen_js_2.client.setConfig({ baseUrl: settings_js_1.settings.baseUrl });
|
|
74
75
|
// Initialize Sentry for SDK error tracking.
|
|
75
76
|
(0, sentry_js_1.initSentry)();
|
|
@@ -80,9 +81,9 @@ function ensureAutoloaded() {
|
|
|
80
81
|
if (isNode && !isBrowser && !settings_js_1.settings.disableH2) {
|
|
81
82
|
try {
|
|
82
83
|
// Pre-warm edge H2 for the configured region so the first
|
|
83
|
-
// SandboxInstance.create() gets an instant session via the
|
|
84
|
-
//
|
|
85
|
-
//
|
|
84
|
+
// SandboxInstance.create() gets an instant data-plane session via the
|
|
85
|
+
// pool. Control-plane H2 is intentionally not warmed; its cold burst
|
|
86
|
+
// relies on pool deduplication instead.
|
|
86
87
|
const region = settings_js_1.settings.region;
|
|
87
88
|
if (region) {
|
|
88
89
|
Promise.resolve().then(() => __importStar(require("./h2pool.js"))).then(({ h2Pool }) => {
|
|
@@ -28,8 +28,8 @@ function missingCredentialsMessage() {
|
|
|
28
28
|
return "No Blaxel credentials found. Set the BL_API_KEY and BL_WORKSPACE environment variables, or run `bl login`.";
|
|
29
29
|
}
|
|
30
30
|
// Build info - these placeholders are replaced at build time by build:replace-imports
|
|
31
|
-
const BUILD_VERSION = "0.2.
|
|
32
|
-
const BUILD_COMMIT = "
|
|
31
|
+
const BUILD_VERSION = "0.2.90-preview.182";
|
|
32
|
+
const BUILD_COMMIT = "78dad6b3e2d47dcf5d8464b9688b0829ddc3369c";
|
|
33
33
|
const BUILD_SENTRY_DSN = "https://fd5e60e1c9820e1eef5ccebb84a07127@o4508714045276160.ingest.us.sentry.io/4510465864564736";
|
|
34
34
|
const BLAXEL_API_VERSION = "2026-04-16";
|
|
35
35
|
// Cache for config.yaml tracking value
|
|
@@ -250,6 +250,31 @@ class Settings {
|
|
|
250
250
|
}
|
|
251
251
|
return isDenoRuntime();
|
|
252
252
|
}
|
|
253
|
+
// Control-plane-only escape hatch: disables the control-plane H2 wrapper
|
|
254
|
+
// without affecting data-plane (edge) H2. `disableH2` is the global override
|
|
255
|
+
// and is checked separately by callers, so it always wins.
|
|
256
|
+
get disableControlPlaneH2() {
|
|
257
|
+
if (typeof this.config.disableControlPlaneH2 === "boolean") {
|
|
258
|
+
return this.config.disableControlPlaneH2;
|
|
259
|
+
}
|
|
260
|
+
const value = env_js_1.env.BL_DISABLE_CONTROL_PLANE_H2;
|
|
261
|
+
if (value) {
|
|
262
|
+
return ["1", "true", "yes", "on"].includes(value.toLowerCase());
|
|
263
|
+
}
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
// Forces the control-plane H2 wrapper on even when native fetch already
|
|
267
|
+
// supports H2 (undici >= 7). `disableH2`/`disableControlPlaneH2` still win.
|
|
268
|
+
get forceControlPlaneH2() {
|
|
269
|
+
if (typeof this.config.forceControlPlaneH2 === "boolean") {
|
|
270
|
+
return this.config.forceControlPlaneH2;
|
|
271
|
+
}
|
|
272
|
+
const value = env_js_1.env.BL_FORCE_CONTROL_PLANE_H2;
|
|
273
|
+
if (value) {
|
|
274
|
+
return ["1", "true", "yes", "on"].includes(value.toLowerCase());
|
|
275
|
+
}
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
253
278
|
get maxConcurrentH2Requests() {
|
|
254
279
|
if (typeof this.config.maxConcurrentH2Requests === "number") {
|
|
255
280
|
return this.config.maxConcurrentH2Requests;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function undiciSupportsNativeH2(undiciVersion: string | undefined): boolean;
|
|
2
|
+
export declare const nativeFetchSupportsH2: boolean;
|
|
3
|
+
export declare function shouldUseControlPlaneH2(url: URL, h2Disabled: boolean, proxyConfigured?: boolean, nativeH2?: boolean, forceWrapper?: boolean): boolean;
|
|
4
|
+
export declare function controlPlaneFetch(input: Request): Promise<Response>;
|
|
@@ -12,6 +12,22 @@ export type Config = {
|
|
|
12
12
|
apikey?: string;
|
|
13
13
|
workspace?: string;
|
|
14
14
|
disableH2?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Disables only the control-plane HTTP/2 wrapper, leaving data-plane (edge)
|
|
17
|
+
* H2 untouched. Use this to route control-plane calls (api.blaxel.{ai,dev})
|
|
18
|
+
* over native fetch while keeping sandbox/data-plane traffic on the H2 pool.
|
|
19
|
+
* The global `disableH2` flag still wins: when it is true, both planes use
|
|
20
|
+
* native fetch regardless of this value. Defaults to `false` (wrapper on).
|
|
21
|
+
*/
|
|
22
|
+
disableControlPlaneH2?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Forces the control-plane HTTP/2 wrapper on even when the runtime's native
|
|
25
|
+
* fetch already negotiates HTTP/2 (undici >= 8 / Node 26+), where it is
|
|
26
|
+
* otherwise skipped as redundant. Mainly for exercising the pooled path on a
|
|
27
|
+
* modern runtime. `disableH2` and `disableControlPlaneH2` still win.
|
|
28
|
+
* Defaults to `false`.
|
|
29
|
+
*/
|
|
30
|
+
forceControlPlaneH2?: boolean;
|
|
15
31
|
/**
|
|
16
32
|
* Maximum number of concurrent in-flight HTTP/2 requests across the shared
|
|
17
33
|
* H2 session pool. `0` or `undefined` means unlimited (current behavior).
|
|
@@ -93,6 +109,8 @@ declare class Settings {
|
|
|
93
109
|
get tracking(): boolean;
|
|
94
110
|
get region(): string | undefined;
|
|
95
111
|
get disableH2(): boolean;
|
|
112
|
+
get disableControlPlaneH2(): boolean;
|
|
113
|
+
get forceControlPlaneH2(): boolean;
|
|
96
114
|
get maxConcurrentH2Requests(): number;
|
|
97
115
|
get maxConcurrentUploadH2Requests(): number;
|
|
98
116
|
get h2StreamWindowSize(): number;
|