@blaxel/core 0.2.79-preview.130 → 0.2.79-preview.132

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,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.79-preview.130";
9
- const BUILD_COMMIT = "7f4924b21bd257cad5bdf35bd3a2db8d99876495";
8
+ const BUILD_VERSION = "0.2.79-preview.132";
9
+ const BUILD_COMMIT = "5fb1f8667d2d0bc7b45ca640257677c647eb5e59";
10
10
  const BUILD_SENTRY_DSN = "https://fd5e60e1c9820e1eef5ccebb84a07127@o4508714045276160.ingest.us.sentry.io/4510465864564736";
11
11
  // Cache for config.yaml tracking value
12
12
  let configTrackingValue = null;
@@ -1,6 +1,38 @@
1
+ import { settings } from "../../common/settings.js";
1
2
  import { SandboxAction } from "../action.js";
2
3
  export class SandboxNetwork extends SandboxAction {
3
4
  constructor(sandbox) {
4
5
  super(sandbox);
5
6
  }
7
+ /**
8
+ * Fetch a resource served on a sandbox port.
9
+ * The request is proxied through the sandbox's `/port/{port}` endpoint.
10
+ *
11
+ * @param port - The port number inside the sandbox
12
+ * @param path - Optional path appended after the port (default: "/")
13
+ * @param init - Standard RequestInit options forwarded to fetch
14
+ */
15
+ async fetch(port, path = "/", init) {
16
+ const normalizedPath = path.startsWith("/") ? path : `/${path}`;
17
+ const url = `${this.url}/port/${port}${normalizedPath}`;
18
+ const headers = (this.sandbox.forceUrl ? this.sandbox.headers : undefined) ?? settings.headers;
19
+ const initHeaders = {};
20
+ if (init?.headers) {
21
+ const entries = init.headers instanceof Headers
22
+ ? init.headers.entries()
23
+ : Array.isArray(init.headers)
24
+ ? init.headers.values()
25
+ : Object.entries(init.headers).values();
26
+ for (const [key, value] of entries) {
27
+ initHeaders[key] = value;
28
+ }
29
+ }
30
+ return this.h2Fetch(url, {
31
+ ...init,
32
+ headers: {
33
+ ...headers,
34
+ ...initHeaders,
35
+ },
36
+ });
37
+ }
6
38
  }
@@ -15,7 +15,24 @@ export class SandboxProcess extends SandboxAction {
15
15
  console.error("Stream error:", err);
16
16
  }
17
17
  };
18
+ const processLine = (line) => {
19
+ if (line.startsWith("[keepalive]")) {
20
+ return;
21
+ }
22
+ if (line.startsWith('stdout:')) {
23
+ options.onStdout?.(line.slice(7));
24
+ options.onLog?.(line.slice(7));
25
+ }
26
+ else if (line.startsWith('stderr:')) {
27
+ options.onStderr?.(line.slice(7));
28
+ options.onLog?.(line.slice(7));
29
+ }
30
+ else {
31
+ options.onLog?.(line);
32
+ }
33
+ };
18
34
  const done = (async () => {
35
+ let buffer = '';
19
36
  try {
20
37
  const headers = this.sandbox.forceUrl ? this.sandbox.headers : settings.headers;
21
38
  const stream = await this.h2Fetch(`${this.url}/process/${identifier}/logs/stream`, {
@@ -33,7 +50,6 @@ export class SandboxProcess extends SandboxAction {
33
50
  }
34
51
  const reader = stream.body.getReader();
35
52
  const decoder = new TextDecoder();
36
- let buffer = '';
37
53
  while (true) {
38
54
  const result = await reader.read();
39
55
  if (result.done)
@@ -44,25 +60,21 @@ export class SandboxProcess extends SandboxAction {
44
60
  const lines = buffer.split(/\r?\n/);
45
61
  buffer = lines.pop();
46
62
  for (const line of lines) {
47
- if (line.startsWith("[keepalive]")) {
48
- continue;
49
- }
50
- if (line.startsWith('stdout:')) {
51
- options.onStdout?.(line.slice(7));
52
- options.onLog?.(line.slice(7));
53
- }
54
- else if (line.startsWith('stderr:')) {
55
- options.onStderr?.(line.slice(7));
56
- options.onLog?.(line.slice(7));
57
- }
58
- else {
59
- options.onLog?.(line);
60
- }
63
+ processLine(line);
61
64
  }
62
65
  }
66
+ // Flush the TextDecoder and process any remaining buffered data
67
+ buffer += decoder.decode();
68
+ if (buffer.trim()) {
69
+ processLine(buffer);
70
+ }
63
71
  }
64
72
  catch (err) {
65
73
  if (err && typeof err === 'object' && 'name' in err && err.name === 'AbortError') {
74
+ // Process remaining buffer before returning on abort
75
+ if (buffer.trim()) {
76
+ processLine(buffer);
77
+ }
66
78
  return;
67
79
  }
68
80
  handleError(err instanceof Error ? err : new Error('Unknown stream error'));
@@ -212,15 +224,51 @@ export class SandboxProcess extends SandboxAction {
212
224
  }
213
225
  }
214
226
  }
215
- // Process any remaining buffer
227
+ // Flush the TextDecoder and process any remaining buffered data
228
+ buffer += decoder.decode();
216
229
  if (buffer.trim()) {
217
- if (buffer.startsWith('result:')) {
218
- const jsonStr = buffer.slice(7);
219
- try {
220
- result = JSON.parse(jsonStr);
230
+ let parsed = null;
231
+ try {
232
+ parsed = JSON.parse(buffer.trim());
233
+ }
234
+ catch (e) {
235
+ // Not valid JSON — try legacy result: prefix format
236
+ if (buffer.startsWith('result:')) {
237
+ const jsonStr = buffer.slice(7);
238
+ try {
239
+ result = JSON.parse(jsonStr);
240
+ }
241
+ catch {
242
+ throw new Error(`Failed to parse result JSON: ${jsonStr}`);
243
+ }
244
+ }
245
+ else {
246
+ // Not a legacy result line — surface the original parse error
247
+ throw e;
221
248
  }
222
- catch {
223
- throw new Error(`Failed to parse result JSON: ${jsonStr}`);
249
+ }
250
+ if (parsed) {
251
+ switch (parsed.type) {
252
+ case 'stdout':
253
+ if (parsed.data) {
254
+ options.onStdout?.(parsed.data);
255
+ options.onLog?.(parsed.data);
256
+ }
257
+ break;
258
+ case 'stderr':
259
+ if (parsed.data) {
260
+ options.onStderr?.(parsed.data);
261
+ options.onLog?.(parsed.data);
262
+ }
263
+ break;
264
+ case 'result':
265
+ try {
266
+ result = JSON.parse(parsed.data);
267
+ }
268
+ catch {
269
+ throw new Error(`Failed to parse result JSON: ${parsed.data}`);
270
+ }
271
+ break;
224
272
  }
225
273
  }
226
274
  }
@@ -74,6 +74,16 @@ export class SandboxInstance {
74
74
  get expiresIn() {
75
75
  return this.sandbox.expiresIn;
76
76
  }
77
+ /**
78
+ * Fetch a resource served on a sandbox port.
79
+ *
80
+ * @param port - The port number inside the sandbox
81
+ * @param path - Optional path appended after the port (default: "/")
82
+ * @param init - Standard RequestInit options forwarded to fetch
83
+ */
84
+ async fetch(port, path = "/", init) {
85
+ return this.network.fetch(port, path, init);
86
+ }
77
87
  /* eslint-disable */
78
88
  async wait({ maxWait = 60000, interval = 1000 } = {}) {
79
89
  logger.warn("⚠️ Warning: sandbox.wait() is deprecated. You don't need to wait for the sandbox to be deployed anymore.");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blaxel/core",
3
- "version": "0.2.79-preview.130",
3
+ "version": "0.2.79-preview.132",
4
4
  "description": "Blaxel Core SDK for TypeScript",
5
5
  "license": "MIT",
6
6
  "author": "Blaxel, INC (https://blaxel.ai)",