@blaxel/core 0.2.1-dev12 → 0.2.1-dev2
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/common/internal.d.ts +1 -1
- package/dist/common/internal.js +6 -3
- package/dist/common/settings.d.ts +0 -1
- package/dist/common/settings.js +1 -7
- package/dist/sandbox/action.d.ts +0 -1
- package/dist/sandbox/action.js +2 -35
- package/dist/sandbox/client/sdk.gen.d.ts +6 -9
- package/dist/sandbox/client/sdk.gen.js +3 -14
- package/dist/sandbox/client/types.gen.d.ts +17 -33
- package/dist/sandbox/filesystem.d.ts +0 -26
- package/dist/sandbox/filesystem.js +0 -191
- package/dist/sandbox/process.d.ts +0 -26
- package/dist/sandbox/process.js +0 -183
- package/dist/telemetry/telemetry.d.ts +0 -1
- package/dist/telemetry/telemetry.js +0 -14
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare function getAlphanumericLimitedHash(input: string, maxSize
|
|
1
|
+
export declare function getAlphanumericLimitedHash(input: string, maxSize: number): string;
|
|
2
2
|
export declare function getGlobalUniqueHash(workspace: string, type: string, name: string): string;
|
package/dist/common/internal.js
CHANGED
|
@@ -6,9 +6,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.getAlphanumericLimitedHash = getAlphanumericLimitedHash;
|
|
7
7
|
exports.getGlobalUniqueHash = getGlobalUniqueHash;
|
|
8
8
|
const crypto_1 = __importDefault(require("crypto"));
|
|
9
|
-
function getAlphanumericLimitedHash(input, maxSize
|
|
10
|
-
const hash = crypto_1.default.createHash(
|
|
11
|
-
|
|
9
|
+
function getAlphanumericLimitedHash(input, maxSize) {
|
|
10
|
+
const hash = crypto_1.default.createHash("sha256").update(input).digest("base64");
|
|
11
|
+
const alphanumeric = hash.replace(/[^a-z0-9]+/g, "");
|
|
12
|
+
return alphanumeric.length > maxSize
|
|
13
|
+
? alphanumeric.substring(0, maxSize)
|
|
14
|
+
: alphanumeric;
|
|
12
15
|
}
|
|
13
16
|
function getGlobalUniqueHash(workspace, type, name) {
|
|
14
17
|
const globalUniqueName = `${workspace}-${type}-${name}`;
|
package/dist/common/settings.js
CHANGED
|
@@ -72,10 +72,7 @@ class Settings {
|
|
|
72
72
|
return env_js_1.env.BL_TYPE || "agents";
|
|
73
73
|
}
|
|
74
74
|
get runInternalHostname() {
|
|
75
|
-
|
|
76
|
-
return "";
|
|
77
|
-
}
|
|
78
|
-
return env_js_1.env.BL_RUN_INTERNAL_HOST || "";
|
|
75
|
+
return env_js_1.env.BL_RUN_INTERNAL_HOSTNAME || "";
|
|
79
76
|
}
|
|
80
77
|
get runInternalProtocol() {
|
|
81
78
|
return env_js_1.env.BL_RUN_INTERNAL_PROTOCOL || "https";
|
|
@@ -83,9 +80,6 @@ class Settings {
|
|
|
83
80
|
get blCloud() {
|
|
84
81
|
return env_js_1.env.BL_CLOUD === "true";
|
|
85
82
|
}
|
|
86
|
-
get generation() {
|
|
87
|
-
return env_js_1.env.BL_GENERATION || "";
|
|
88
|
-
}
|
|
89
83
|
get loggerType() {
|
|
90
84
|
return env_js_1.env.BL_LOGGER || "http";
|
|
91
85
|
}
|
package/dist/sandbox/action.d.ts
CHANGED
package/dist/sandbox/action.js
CHANGED
|
@@ -61,9 +61,8 @@ class SandboxAction {
|
|
|
61
61
|
get url() {
|
|
62
62
|
if (this.forcedUrl)
|
|
63
63
|
return this.forcedUrl;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
// if (settings.runInternalHostname) return this.internalUrl;
|
|
64
|
+
if (settings_js_1.settings.runInternalHostname)
|
|
65
|
+
return this.internalUrl;
|
|
67
66
|
return this.externalUrl;
|
|
68
67
|
}
|
|
69
68
|
handleResponseError(response, data, error) {
|
|
@@ -71,37 +70,5 @@ class SandboxAction {
|
|
|
71
70
|
throw new ResponseError(response, data, error);
|
|
72
71
|
}
|
|
73
72
|
}
|
|
74
|
-
websocket(path) {
|
|
75
|
-
let ws = null;
|
|
76
|
-
// Build ws:// or wss:// URL from baseUrl
|
|
77
|
-
let baseUrl = this.url.replace(/^http/, 'ws');
|
|
78
|
-
if (baseUrl.endsWith('/'))
|
|
79
|
-
baseUrl = baseUrl.slice(0, -1);
|
|
80
|
-
const wsUrl = `${baseUrl}/ws/${path}?token=${settings_js_1.settings.token}`;
|
|
81
|
-
// Use isomorphic WebSocket: browser or Node.js
|
|
82
|
-
let WS = undefined;
|
|
83
|
-
if (typeof globalThis.WebSocket !== 'undefined') {
|
|
84
|
-
WS = globalThis.WebSocket;
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
try {
|
|
88
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
89
|
-
WS = require('ws');
|
|
90
|
-
}
|
|
91
|
-
catch {
|
|
92
|
-
WS = undefined;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
if (!WS)
|
|
96
|
-
throw new Error('WebSocket is not available in this environment');
|
|
97
|
-
try {
|
|
98
|
-
ws = typeof WS === 'function' ? new WS(wsUrl) : new WS(wsUrl);
|
|
99
|
-
}
|
|
100
|
-
catch (err) {
|
|
101
|
-
console.error('WebSocket connection error:', err);
|
|
102
|
-
throw err;
|
|
103
|
-
}
|
|
104
|
-
return ws;
|
|
105
|
-
}
|
|
106
73
|
}
|
|
107
74
|
exports.SandboxAction = SandboxAction;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Options as ClientOptions, TDataShape, Client } from '@hey-api/client-fetch';
|
|
2
|
-
import type { DeleteFilesystemByPathData, GetFilesystemByPathData, PutFilesystemByPathData, DeleteNetworkProcessByPidMonitorData, PostNetworkProcessByPidMonitorData, GetNetworkProcessByPidPortsData, GetProcessData, PostProcessData, DeleteProcessByIdentifierData, GetProcessByIdentifierData, DeleteProcessByIdentifierKillData, GetProcessByIdentifierLogsData, GetProcessByIdentifierLogsStreamData
|
|
2
|
+
import type { DeleteFilesystemByPathData, GetFilesystemByPathData, PutFilesystemByPathData, DeleteNetworkProcessByPidMonitorData, PostNetworkProcessByPidMonitorData, GetNetworkProcessByPidPortsData, GetProcessData, PostProcessData, DeleteProcessByIdentifierData, GetProcessByIdentifierData, DeleteProcessByIdentifierKillData, GetProcessByIdentifierLogsData, GetProcessByIdentifierLogsStreamData } from './types.gen';
|
|
3
3
|
export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = ClientOptions<TData, ThrowOnError> & {
|
|
4
4
|
/**
|
|
5
5
|
* You can provide a client instance returned by `createClient()` instead of
|
|
@@ -82,12 +82,9 @@ export declare const getProcessByIdentifierLogs: <ThrowOnError extends boolean =
|
|
|
82
82
|
[key: string]: string;
|
|
83
83
|
}, import("./types.gen").ErrorResponse, ThrowOnError>;
|
|
84
84
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
85
|
+
* Get process logs in realtime
|
|
86
|
+
* Get the stdout and stderr output of a process in realtime
|
|
87
87
|
*/
|
|
88
|
-
export declare const getProcessByIdentifierLogsStream: <ThrowOnError extends boolean = false>(options: Options<GetProcessByIdentifierLogsStreamData, ThrowOnError>) => import("@hey-api/client-fetch").RequestResult<
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
* Streams the path of modified files (one per line) in the given directory. Closes when the client disconnects.
|
|
92
|
-
*/
|
|
93
|
-
export declare const getWatchFilesystemByPath: <ThrowOnError extends boolean = false>(options: Options<GetWatchFilesystemByPathData, ThrowOnError>) => import("@hey-api/client-fetch").RequestResult<string, import("./types.gen").ErrorResponse, ThrowOnError>;
|
|
88
|
+
export declare const getProcessByIdentifierLogsStream: <ThrowOnError extends boolean = false>(options: Options<GetProcessByIdentifierLogsStreamData, ThrowOnError>) => import("@hey-api/client-fetch").RequestResult<{
|
|
89
|
+
[key: string]: string;
|
|
90
|
+
}, import("./types.gen").ErrorResponse, ThrowOnError>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// This file is auto-generated by @hey-api/openapi-ts
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.
|
|
4
|
+
exports.getProcessByIdentifierLogsStream = exports.getProcessByIdentifierLogs = exports.deleteProcessByIdentifierKill = exports.getProcessByIdentifier = exports.deleteProcessByIdentifier = exports.postProcess = exports.getProcess = exports.getNetworkProcessByPidPorts = exports.postNetworkProcessByPidMonitor = exports.deleteNetworkProcessByPidMonitor = exports.putFilesystemByPath = exports.getFilesystemByPath = exports.deleteFilesystemByPath = void 0;
|
|
5
5
|
const client_gen_1 = require("./client.gen");
|
|
6
6
|
/**
|
|
7
7
|
* Delete file or directory
|
|
@@ -152,8 +152,8 @@ const getProcessByIdentifierLogs = (options) => {
|
|
|
152
152
|
};
|
|
153
153
|
exports.getProcessByIdentifierLogs = getProcessByIdentifierLogs;
|
|
154
154
|
/**
|
|
155
|
-
*
|
|
156
|
-
*
|
|
155
|
+
* Get process logs in realtime
|
|
156
|
+
* Get the stdout and stderr output of a process in realtime
|
|
157
157
|
*/
|
|
158
158
|
const getProcessByIdentifierLogsStream = (options) => {
|
|
159
159
|
return (options.client ?? client_gen_1.client).get({
|
|
@@ -162,14 +162,3 @@ const getProcessByIdentifierLogsStream = (options) => {
|
|
|
162
162
|
});
|
|
163
163
|
};
|
|
164
164
|
exports.getProcessByIdentifierLogsStream = getProcessByIdentifierLogsStream;
|
|
165
|
-
/**
|
|
166
|
-
* Stream file modification events in a directory
|
|
167
|
-
* Streams the path of modified files (one per line) in the given directory. Closes when the client disconnects.
|
|
168
|
-
*/
|
|
169
|
-
const getWatchFilesystemByPath = (options) => {
|
|
170
|
-
return (options.client ?? client_gen_1.client).get({
|
|
171
|
-
url: '/watch/filesystem/{path}',
|
|
172
|
-
...options
|
|
173
|
-
});
|
|
174
|
-
};
|
|
175
|
-
exports.getWatchFilesystemByPath = getWatchFilesystemByPath;
|
|
@@ -41,6 +41,7 @@ export type ProcessKillRequest = {
|
|
|
41
41
|
export type ProcessRequest = {
|
|
42
42
|
command: string;
|
|
43
43
|
name?: string;
|
|
44
|
+
streamLogs?: boolean;
|
|
44
45
|
timeout?: number;
|
|
45
46
|
waitForCompletion?: boolean;
|
|
46
47
|
waitForPorts?: Array<number>;
|
|
@@ -393,7 +394,12 @@ export type GetProcessByIdentifierLogsData = {
|
|
|
393
394
|
*/
|
|
394
395
|
identifier: string;
|
|
395
396
|
};
|
|
396
|
-
query?:
|
|
397
|
+
query?: {
|
|
398
|
+
/**
|
|
399
|
+
* Stream logs
|
|
400
|
+
*/
|
|
401
|
+
stream?: boolean;
|
|
402
|
+
};
|
|
397
403
|
url: '/process/{identifier}/logs';
|
|
398
404
|
};
|
|
399
405
|
export type GetProcessByIdentifierLogsErrors = {
|
|
@@ -424,7 +430,12 @@ export type GetProcessByIdentifierLogsStreamData = {
|
|
|
424
430
|
*/
|
|
425
431
|
identifier: string;
|
|
426
432
|
};
|
|
427
|
-
query?:
|
|
433
|
+
query?: {
|
|
434
|
+
/**
|
|
435
|
+
* Stream logs
|
|
436
|
+
*/
|
|
437
|
+
stream?: boolean;
|
|
438
|
+
};
|
|
428
439
|
url: '/process/{identifier}/logs/stream';
|
|
429
440
|
};
|
|
430
441
|
export type GetProcessByIdentifierLogsStreamErrors = {
|
|
@@ -440,40 +451,13 @@ export type GetProcessByIdentifierLogsStreamErrors = {
|
|
|
440
451
|
export type GetProcessByIdentifierLogsStreamError = GetProcessByIdentifierLogsStreamErrors[keyof GetProcessByIdentifierLogsStreamErrors];
|
|
441
452
|
export type GetProcessByIdentifierLogsStreamResponses = {
|
|
442
453
|
/**
|
|
443
|
-
*
|
|
454
|
+
* Process logs
|
|
444
455
|
*/
|
|
445
|
-
200:
|
|
446
|
-
|
|
447
|
-
export type GetProcessByIdentifierLogsStreamResponse = GetProcessByIdentifierLogsStreamResponses[keyof GetProcessByIdentifierLogsStreamResponses];
|
|
448
|
-
export type GetWatchFilesystemByPathData = {
|
|
449
|
-
body?: never;
|
|
450
|
-
path: {
|
|
451
|
-
/**
|
|
452
|
-
* Directory path to watch
|
|
453
|
-
*/
|
|
454
|
-
path: string;
|
|
456
|
+
200: {
|
|
457
|
+
[key: string]: string;
|
|
455
458
|
};
|
|
456
|
-
query?: never;
|
|
457
|
-
url: '/watch/filesystem/{path}';
|
|
458
|
-
};
|
|
459
|
-
export type GetWatchFilesystemByPathErrors = {
|
|
460
|
-
/**
|
|
461
|
-
* Invalid path
|
|
462
|
-
*/
|
|
463
|
-
400: ErrorResponse;
|
|
464
|
-
/**
|
|
465
|
-
* Internal server error
|
|
466
|
-
*/
|
|
467
|
-
500: ErrorResponse;
|
|
468
459
|
};
|
|
469
|
-
export type
|
|
470
|
-
export type GetWatchFilesystemByPathResponses = {
|
|
471
|
-
/**
|
|
472
|
-
* Stream of modified file paths, one per line
|
|
473
|
-
*/
|
|
474
|
-
200: string;
|
|
475
|
-
};
|
|
476
|
-
export type GetWatchFilesystemByPathResponse = GetWatchFilesystemByPathResponses[keyof GetWatchFilesystemByPathResponses];
|
|
460
|
+
export type GetProcessByIdentifierLogsStreamResponse = GetProcessByIdentifierLogsStreamResponses[keyof GetProcessByIdentifierLogsStreamResponses];
|
|
477
461
|
export type ClientOptions = {
|
|
478
462
|
baseUrl: `${string}://localhost:8080` | (string & {});
|
|
479
463
|
};
|
|
@@ -14,31 +14,5 @@ export declare class SandboxFileSystem extends SandboxAction {
|
|
|
14
14
|
rm(path: string, recursive?: boolean): Promise<SuccessResponse>;
|
|
15
15
|
ls(path: string): Promise<Directory>;
|
|
16
16
|
cp(source: string, destination: string): Promise<CopyResponse>;
|
|
17
|
-
/**
|
|
18
|
-
* Watch for changes in a directory. Calls the callback with the changed file path (and optionally its content).
|
|
19
|
-
* Returns a handle with a close() method to stop watching.
|
|
20
|
-
* @param path Directory to watch
|
|
21
|
-
* @param callback Function called on each change: (filePath, content?)
|
|
22
|
-
* @param withContent If true, also fetches and passes the file content (default: false)
|
|
23
|
-
*/
|
|
24
|
-
watch(path: string, callback: (filePath: string, content?: string) => void | Promise<void>, options?: {
|
|
25
|
-
ws?: boolean;
|
|
26
|
-
onError?: (error: Error) => void;
|
|
27
|
-
withContent: boolean;
|
|
28
|
-
}): {
|
|
29
|
-
close: () => void;
|
|
30
|
-
};
|
|
31
|
-
wsWatch(path: string, callback: (filePath: string, content?: string) => void | Promise<void>, options?: {
|
|
32
|
-
onError?: (error: Error) => void;
|
|
33
|
-
withContent: boolean;
|
|
34
|
-
}): {
|
|
35
|
-
close: () => void;
|
|
36
|
-
};
|
|
37
|
-
sseWatch(path: string, callback: (filePath: string, content?: string) => void | Promise<void>, options?: {
|
|
38
|
-
onError?: (error: Error) => void;
|
|
39
|
-
withContent: boolean;
|
|
40
|
-
}): {
|
|
41
|
-
close: () => void;
|
|
42
|
-
};
|
|
43
17
|
private formatPath;
|
|
44
18
|
}
|
|
@@ -111,197 +111,6 @@ class SandboxFileSystem extends action_js_1.SandboxAction {
|
|
|
111
111
|
}
|
|
112
112
|
throw new Error("Unsupported file type");
|
|
113
113
|
}
|
|
114
|
-
/**
|
|
115
|
-
* Watch for changes in a directory. Calls the callback with the changed file path (and optionally its content).
|
|
116
|
-
* Returns a handle with a close() method to stop watching.
|
|
117
|
-
* @param path Directory to watch
|
|
118
|
-
* @param callback Function called on each change: (filePath, content?)
|
|
119
|
-
* @param withContent If true, also fetches and passes the file content (default: false)
|
|
120
|
-
*/
|
|
121
|
-
watch(path, callback, options) {
|
|
122
|
-
if (options?.ws) {
|
|
123
|
-
return this.wsWatch(path, callback, options);
|
|
124
|
-
}
|
|
125
|
-
return this.sseWatch(path, callback, options);
|
|
126
|
-
}
|
|
127
|
-
wsWatch(path, callback, options) {
|
|
128
|
-
path = this.formatPath(path);
|
|
129
|
-
let closed = false;
|
|
130
|
-
let ws = this.websocket(`watch/filesystem${path.startsWith('/') ? path : '/' + path}`);
|
|
131
|
-
let pingInterval = null;
|
|
132
|
-
let pongTimeout = null;
|
|
133
|
-
const PING_INTERVAL_MS = 30000;
|
|
134
|
-
const PONG_TIMEOUT_MS = 10000;
|
|
135
|
-
function sendPing() {
|
|
136
|
-
if (ws && ws.readyState === ws.OPEN) {
|
|
137
|
-
try {
|
|
138
|
-
ws.send(JSON.stringify({ type: 'ping' }));
|
|
139
|
-
}
|
|
140
|
-
catch { }
|
|
141
|
-
// Set pong timeout
|
|
142
|
-
if (pongTimeout)
|
|
143
|
-
clearTimeout(pongTimeout);
|
|
144
|
-
pongTimeout = setTimeout(() => {
|
|
145
|
-
// No pong received in time, close connection
|
|
146
|
-
if (ws && typeof ws.close === 'function')
|
|
147
|
-
ws.close();
|
|
148
|
-
}, PONG_TIMEOUT_MS);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
if (ws) {
|
|
152
|
-
ws.onmessage = async (event) => {
|
|
153
|
-
if (closed)
|
|
154
|
-
return;
|
|
155
|
-
let data;
|
|
156
|
-
try {
|
|
157
|
-
data = typeof event.data === 'string' ? event.data : event.data;
|
|
158
|
-
if (!data)
|
|
159
|
-
return;
|
|
160
|
-
// Accept both JSON and plain string (file path)
|
|
161
|
-
let payload;
|
|
162
|
-
try {
|
|
163
|
-
payload = JSON.parse(data);
|
|
164
|
-
}
|
|
165
|
-
catch {
|
|
166
|
-
payload = { name: data, event: undefined };
|
|
167
|
-
}
|
|
168
|
-
// Handle ping/pong
|
|
169
|
-
if (payload.type === 'ping') {
|
|
170
|
-
// Respond to ping with pong
|
|
171
|
-
if (ws && ws.readyState === ws.OPEN) {
|
|
172
|
-
try {
|
|
173
|
-
ws.send(JSON.stringify({ type: 'pong' }));
|
|
174
|
-
}
|
|
175
|
-
catch { }
|
|
176
|
-
}
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
if (payload.type === 'pong') {
|
|
180
|
-
// Pong received, clear pong timeout
|
|
181
|
-
if (pongTimeout)
|
|
182
|
-
clearTimeout(pongTimeout);
|
|
183
|
-
pongTimeout = null;
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
const filePath = payload.name || payload.path || data;
|
|
187
|
-
if (!filePath)
|
|
188
|
-
return;
|
|
189
|
-
if (options?.withContent) {
|
|
190
|
-
try {
|
|
191
|
-
const content = await this.read(filePath);
|
|
192
|
-
await callback(filePath, content);
|
|
193
|
-
}
|
|
194
|
-
catch (e) {
|
|
195
|
-
await callback(filePath, undefined);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
199
|
-
await callback(filePath);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
catch (err) {
|
|
203
|
-
if (options?.onError)
|
|
204
|
-
options.onError(err);
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
ws.onerror = (err) => {
|
|
208
|
-
if (options?.onError)
|
|
209
|
-
options.onError(err instanceof Error ? err : new Error(String(err)));
|
|
210
|
-
closed = true;
|
|
211
|
-
if (ws && typeof ws.close === 'function')
|
|
212
|
-
ws.close();
|
|
213
|
-
};
|
|
214
|
-
ws.onclose = () => {
|
|
215
|
-
closed = true;
|
|
216
|
-
ws = null;
|
|
217
|
-
if (pingInterval)
|
|
218
|
-
clearInterval(pingInterval);
|
|
219
|
-
if (pongTimeout)
|
|
220
|
-
clearTimeout(pongTimeout);
|
|
221
|
-
};
|
|
222
|
-
// Start ping interval
|
|
223
|
-
pingInterval = setInterval(sendPing, PING_INTERVAL_MS);
|
|
224
|
-
}
|
|
225
|
-
return {
|
|
226
|
-
close: () => {
|
|
227
|
-
closed = true;
|
|
228
|
-
if (ws && typeof ws.close === 'function')
|
|
229
|
-
ws.close();
|
|
230
|
-
ws = null;
|
|
231
|
-
if (pingInterval)
|
|
232
|
-
clearInterval(pingInterval);
|
|
233
|
-
if (pongTimeout)
|
|
234
|
-
clearTimeout(pongTimeout);
|
|
235
|
-
},
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
sseWatch(path, callback, options) {
|
|
239
|
-
path = this.formatPath(path);
|
|
240
|
-
let closed = false;
|
|
241
|
-
let controller = new AbortController();
|
|
242
|
-
const start = async () => {
|
|
243
|
-
const { response, data, error } = await (0, index_js_1.getWatchFilesystemByPath)({
|
|
244
|
-
path: { path },
|
|
245
|
-
baseUrl: this.url,
|
|
246
|
-
parseAs: 'stream',
|
|
247
|
-
signal: controller.signal,
|
|
248
|
-
});
|
|
249
|
-
if (error)
|
|
250
|
-
throw error;
|
|
251
|
-
const stream = data ?? response.body;
|
|
252
|
-
if (!stream)
|
|
253
|
-
throw new Error('No stream returned');
|
|
254
|
-
const reader = stream.getReader();
|
|
255
|
-
let buffer = '';
|
|
256
|
-
const decoder = new TextDecoder();
|
|
257
|
-
try {
|
|
258
|
-
while (!closed) {
|
|
259
|
-
const { value, done } = await reader.read();
|
|
260
|
-
if (done)
|
|
261
|
-
break;
|
|
262
|
-
buffer += decoder.decode(value, { stream: true });
|
|
263
|
-
let lines = buffer.split('\n');
|
|
264
|
-
buffer = lines.pop();
|
|
265
|
-
for (const line of lines) {
|
|
266
|
-
const filePath = line.trim();
|
|
267
|
-
if (!filePath)
|
|
268
|
-
continue;
|
|
269
|
-
if (options?.withContent) {
|
|
270
|
-
try {
|
|
271
|
-
const content = await this.read(filePath);
|
|
272
|
-
await callback(filePath, content);
|
|
273
|
-
}
|
|
274
|
-
catch (e) {
|
|
275
|
-
await callback(filePath, undefined);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
else {
|
|
279
|
-
await callback(filePath);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
finally {
|
|
285
|
-
reader.releaseLock();
|
|
286
|
-
}
|
|
287
|
-
};
|
|
288
|
-
start().catch((err) => {
|
|
289
|
-
// Suppress AbortError when closing
|
|
290
|
-
if (!(err && err.name === 'AbortError')) {
|
|
291
|
-
if (options?.onError) {
|
|
292
|
-
options.onError(err);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
closed = true;
|
|
296
|
-
controller?.abort();
|
|
297
|
-
});
|
|
298
|
-
return {
|
|
299
|
-
close: () => {
|
|
300
|
-
closed = true;
|
|
301
|
-
controller?.abort();
|
|
302
|
-
},
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
114
|
formatPath(path) {
|
|
306
115
|
if (path === "/") {
|
|
307
116
|
return path;
|
|
@@ -3,33 +3,7 @@ import { SandboxAction } from "./action.js";
|
|
|
3
3
|
import { DeleteProcessByIdentifierKillResponse, DeleteProcessByIdentifierResponse, GetProcessByIdentifierResponse, GetProcessResponse, PostProcessResponse, ProcessRequest } from "./client/index.js";
|
|
4
4
|
export declare class SandboxProcess extends SandboxAction {
|
|
5
5
|
constructor(sandbox: Sandbox);
|
|
6
|
-
streamLogs(identifier: string, options: {
|
|
7
|
-
ws?: boolean;
|
|
8
|
-
onLog?: (log: string) => void;
|
|
9
|
-
onStdout?: (stdout: string) => void;
|
|
10
|
-
onStderr?: (stderr: string) => void;
|
|
11
|
-
}): {
|
|
12
|
-
close: () => void;
|
|
13
|
-
};
|
|
14
|
-
wsStreamLogs(identifier: string, options: {
|
|
15
|
-
onLog?: (log: string) => void;
|
|
16
|
-
onStdout?: (stdout: string) => void;
|
|
17
|
-
onStderr?: (stderr: string) => void;
|
|
18
|
-
}): {
|
|
19
|
-
close: () => void;
|
|
20
|
-
};
|
|
21
|
-
sseStreamLogs(identifier: string, options: {
|
|
22
|
-
onLog?: (log: string) => void;
|
|
23
|
-
onStdout?: (stdout: string) => void;
|
|
24
|
-
onStderr?: (stderr: string) => void;
|
|
25
|
-
}): {
|
|
26
|
-
close: () => void;
|
|
27
|
-
};
|
|
28
6
|
exec(process: ProcessRequest): Promise<PostProcessResponse>;
|
|
29
|
-
wait(identifier: string, { maxWait, interval }?: {
|
|
30
|
-
maxWait?: number;
|
|
31
|
-
interval?: number;
|
|
32
|
-
}): Promise<GetProcessByIdentifierResponse>;
|
|
33
7
|
get(identifier: string): Promise<GetProcessByIdentifierResponse>;
|
|
34
8
|
list(): Promise<GetProcessResponse>;
|
|
35
9
|
stop(identifier: string): Promise<DeleteProcessByIdentifierResponse>;
|
package/dist/sandbox/process.js
CHANGED
|
@@ -1,176 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SandboxProcess = void 0;
|
|
4
|
-
const settings_js_1 = require("../common/settings.js");
|
|
5
4
|
const action_js_1 = require("./action.js");
|
|
6
5
|
const index_js_1 = require("./client/index.js");
|
|
7
6
|
class SandboxProcess extends action_js_1.SandboxAction {
|
|
8
7
|
constructor(sandbox) {
|
|
9
8
|
super(sandbox);
|
|
10
9
|
}
|
|
11
|
-
streamLogs(identifier, options) {
|
|
12
|
-
if (options.ws) {
|
|
13
|
-
return this.wsStreamLogs(identifier, options);
|
|
14
|
-
}
|
|
15
|
-
return this.sseStreamLogs(identifier, options);
|
|
16
|
-
}
|
|
17
|
-
wsStreamLogs(identifier, options) {
|
|
18
|
-
let closed = false;
|
|
19
|
-
let ws = this.websocket(`process/${identifier}/logs/stream`);
|
|
20
|
-
let pingInterval = null;
|
|
21
|
-
let pongTimeout = null;
|
|
22
|
-
const PING_INTERVAL_MS = 30000;
|
|
23
|
-
const PONG_TIMEOUT_MS = 10000;
|
|
24
|
-
function sendPing() {
|
|
25
|
-
if (ws && ws.readyState === ws.OPEN) {
|
|
26
|
-
try {
|
|
27
|
-
ws.send(JSON.stringify({ type: 'ping' }));
|
|
28
|
-
}
|
|
29
|
-
catch { }
|
|
30
|
-
// Set pong timeout
|
|
31
|
-
if (pongTimeout)
|
|
32
|
-
clearTimeout(pongTimeout);
|
|
33
|
-
pongTimeout = setTimeout(() => {
|
|
34
|
-
// No pong received in time, close connection
|
|
35
|
-
if (ws && typeof ws.close === 'function')
|
|
36
|
-
ws.close();
|
|
37
|
-
}, PONG_TIMEOUT_MS);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
if (ws) {
|
|
41
|
-
ws.onmessage = (event) => {
|
|
42
|
-
if (closed)
|
|
43
|
-
return;
|
|
44
|
-
let data;
|
|
45
|
-
try {
|
|
46
|
-
data = typeof event.data === 'string' ? event.data : event.data;
|
|
47
|
-
if (!data)
|
|
48
|
-
return;
|
|
49
|
-
let payload;
|
|
50
|
-
try {
|
|
51
|
-
payload = JSON.parse(data);
|
|
52
|
-
}
|
|
53
|
-
catch {
|
|
54
|
-
payload = { log: data };
|
|
55
|
-
}
|
|
56
|
-
// Handle ping/pong
|
|
57
|
-
if (payload.type === 'ping') {
|
|
58
|
-
// Respond to ping with pong
|
|
59
|
-
if (ws && ws.readyState === ws.OPEN) {
|
|
60
|
-
try {
|
|
61
|
-
ws.send(JSON.stringify({ type: 'pong' }));
|
|
62
|
-
}
|
|
63
|
-
catch { }
|
|
64
|
-
}
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
if (payload.type === 'pong') {
|
|
68
|
-
// Pong received, clear pong timeout
|
|
69
|
-
if (pongTimeout)
|
|
70
|
-
clearTimeout(pongTimeout);
|
|
71
|
-
pongTimeout = null;
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
if (payload.type === 'log') {
|
|
75
|
-
const logLine = payload.log || "";
|
|
76
|
-
if (typeof logLine === 'string') {
|
|
77
|
-
if (logLine.startsWith('stdout:')) {
|
|
78
|
-
options.onStdout?.(logLine.slice(7));
|
|
79
|
-
options.onLog?.(logLine.slice(7));
|
|
80
|
-
}
|
|
81
|
-
else if (logLine.startsWith('stderr:')) {
|
|
82
|
-
options.onStderr?.(logLine.slice(7));
|
|
83
|
-
options.onLog?.(logLine.slice(7));
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
options.onLog?.(logLine);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
catch (err) {
|
|
92
|
-
console.error('WebSocket log stream error:', err);
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
ws.onerror = (err) => {
|
|
96
|
-
closed = true;
|
|
97
|
-
if (ws && typeof ws.close === 'function')
|
|
98
|
-
ws.close();
|
|
99
|
-
};
|
|
100
|
-
ws.onclose = () => {
|
|
101
|
-
closed = true;
|
|
102
|
-
ws = null;
|
|
103
|
-
if (pingInterval)
|
|
104
|
-
clearInterval(pingInterval);
|
|
105
|
-
if (pongTimeout)
|
|
106
|
-
clearTimeout(pongTimeout);
|
|
107
|
-
};
|
|
108
|
-
// Start ping interval
|
|
109
|
-
pingInterval = setInterval(sendPing, PING_INTERVAL_MS);
|
|
110
|
-
}
|
|
111
|
-
return {
|
|
112
|
-
close: () => {
|
|
113
|
-
closed = true;
|
|
114
|
-
if (ws && typeof ws.close === 'function')
|
|
115
|
-
ws.close();
|
|
116
|
-
ws = null;
|
|
117
|
-
if (pingInterval)
|
|
118
|
-
clearInterval(pingInterval);
|
|
119
|
-
if (pongTimeout)
|
|
120
|
-
clearTimeout(pongTimeout);
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
sseStreamLogs(identifier, options) {
|
|
125
|
-
const controller = new AbortController();
|
|
126
|
-
(async () => {
|
|
127
|
-
try {
|
|
128
|
-
const stream = await fetch(`${this.url}/process/${identifier}/logs/stream`, {
|
|
129
|
-
method: 'GET',
|
|
130
|
-
signal: controller.signal,
|
|
131
|
-
headers: settings_js_1.settings.headers,
|
|
132
|
-
});
|
|
133
|
-
if (stream.status !== 200) {
|
|
134
|
-
throw new Error(`Failed to stream logs: ${await stream.text()}`);
|
|
135
|
-
}
|
|
136
|
-
if (!stream.body)
|
|
137
|
-
throw new Error('No stream body');
|
|
138
|
-
const reader = stream.body.getReader();
|
|
139
|
-
const decoder = new TextDecoder();
|
|
140
|
-
let buffer = '';
|
|
141
|
-
while (true) {
|
|
142
|
-
const { done, value } = await reader.read();
|
|
143
|
-
if (done)
|
|
144
|
-
break;
|
|
145
|
-
buffer += decoder.decode(value, { stream: true });
|
|
146
|
-
let lines = buffer.split(/\r?\n/);
|
|
147
|
-
buffer = lines.pop();
|
|
148
|
-
for (const line of lines) {
|
|
149
|
-
if (line.startsWith('stdout:')) {
|
|
150
|
-
options.onStdout?.(line.slice(7));
|
|
151
|
-
options.onLog?.(line.slice(7));
|
|
152
|
-
}
|
|
153
|
-
else if (line.startsWith('stderr:')) {
|
|
154
|
-
options.onStderr?.(line.slice(7));
|
|
155
|
-
options.onLog?.(line.slice(7));
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
options.onLog?.(line);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
catch (err) {
|
|
164
|
-
if (err && err.name !== 'AbortError') {
|
|
165
|
-
console.error("Stream error:", err);
|
|
166
|
-
throw err;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
})();
|
|
170
|
-
return {
|
|
171
|
-
close: () => controller.abort(),
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
10
|
async exec(process) {
|
|
175
11
|
const { response, data, error } = await (0, index_js_1.postProcess)({
|
|
176
12
|
body: process,
|
|
@@ -179,25 +15,6 @@ class SandboxProcess extends action_js_1.SandboxAction {
|
|
|
179
15
|
this.handleResponseError(response, data, error);
|
|
180
16
|
return data;
|
|
181
17
|
}
|
|
182
|
-
async wait(identifier, { maxWait = 60000, interval = 1000 } = {}) {
|
|
183
|
-
const startTime = Date.now();
|
|
184
|
-
let status = "running";
|
|
185
|
-
let data = await this.get(identifier);
|
|
186
|
-
while (status === "running") {
|
|
187
|
-
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
188
|
-
try {
|
|
189
|
-
data = await this.get(identifier);
|
|
190
|
-
status = data.status ?? "running";
|
|
191
|
-
}
|
|
192
|
-
catch {
|
|
193
|
-
break;
|
|
194
|
-
}
|
|
195
|
-
if (Date.now() - startTime > maxWait) {
|
|
196
|
-
throw new Error("Process did not finish in time");
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
return data;
|
|
200
|
-
}
|
|
201
18
|
async get(identifier) {
|
|
202
19
|
const { response, data, error } = await (0, index_js_1.getProcessByIdentifier)({
|
|
203
20
|
path: { identifier },
|
|
@@ -55,5 +55,4 @@ export declare const telemetryRegistry: TelemetryRegistry;
|
|
|
55
55
|
* Create a span with the registered provider
|
|
56
56
|
*/
|
|
57
57
|
export declare function startSpan(name: string, options?: BlaxelSpanOptions): BlaxelSpan;
|
|
58
|
-
export declare function withSpan<T>(name: string, fn: () => T, options?: BlaxelSpanOptions): T;
|
|
59
58
|
export {};
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.telemetryRegistry = void 0;
|
|
5
5
|
exports.startSpan = startSpan;
|
|
6
|
-
exports.withSpan = withSpan;
|
|
7
6
|
/**
|
|
8
7
|
* No-operation implementation of Span
|
|
9
8
|
*/
|
|
@@ -58,16 +57,3 @@ exports.telemetryRegistry = TelemetryRegistry.getInstance();
|
|
|
58
57
|
function startSpan(name, options) {
|
|
59
58
|
return exports.telemetryRegistry.getProvider().startSpan(name, options);
|
|
60
59
|
}
|
|
61
|
-
function withSpan(name, fn, options) {
|
|
62
|
-
const span = startSpan(name, options);
|
|
63
|
-
try {
|
|
64
|
-
const result = fn();
|
|
65
|
-
span.end();
|
|
66
|
-
return result;
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
span.recordException(error);
|
|
70
|
-
span.end();
|
|
71
|
-
throw error;
|
|
72
|
-
}
|
|
73
|
-
}
|