instavm 0.4.0 → 0.8.0
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/index.d.mts +12 -2
- package/dist/index.d.ts +12 -2
- package/dist/index.js +23 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +23 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -44,11 +44,11 @@ declare class HTTPClient {
|
|
|
44
44
|
/**
|
|
45
45
|
* POST request with JSON body
|
|
46
46
|
*/
|
|
47
|
-
post<T = any>(url: string, data?: any, headers?: Record<string, string
|
|
47
|
+
post<T = any>(url: string, data?: any, headers?: Record<string, string>, timeout?: number): Promise<T>;
|
|
48
48
|
/**
|
|
49
49
|
* POST request for code execution (uses X-API-Key header like Python client)
|
|
50
50
|
*/
|
|
51
|
-
postExecution<T = any>(url: string, data: any, headers?: Record<string, string
|
|
51
|
+
postExecution<T = any>(url: string, data: any, headers?: Record<string, string>, timeout?: number): Promise<T>;
|
|
52
52
|
/**
|
|
53
53
|
* POST request with form data (for file uploads)
|
|
54
54
|
*/
|
|
@@ -360,6 +360,10 @@ interface DownloadResult {
|
|
|
360
360
|
|
|
361
361
|
interface InstaVMOptions {
|
|
362
362
|
baseURL?: string;
|
|
363
|
+
/**
|
|
364
|
+
* Timeout in milliseconds. Used for HTTP request timeout and sent to API as VM lifetime (in seconds).
|
|
365
|
+
* Default: 300000 (5 minutes)
|
|
366
|
+
*/
|
|
363
367
|
timeout?: number;
|
|
364
368
|
maxRetries?: number;
|
|
365
369
|
retryDelay?: number;
|
|
@@ -374,6 +378,7 @@ declare class InstaVM {
|
|
|
374
378
|
private _sessionId;
|
|
375
379
|
readonly browser: BrowserManager;
|
|
376
380
|
readonly local: boolean;
|
|
381
|
+
private readonly timeout;
|
|
377
382
|
constructor(apiKey: string, options?: InstaVMOptions);
|
|
378
383
|
/**
|
|
379
384
|
* Ensure operation is not called in local mode
|
|
@@ -381,6 +386,11 @@ declare class InstaVM {
|
|
|
381
386
|
private ensureNotLocal;
|
|
382
387
|
/**
|
|
383
388
|
* Execute code synchronously
|
|
389
|
+
*
|
|
390
|
+
* @param command - Command to execute
|
|
391
|
+
* @param options - Execution options
|
|
392
|
+
* @param options.timeout - Request timeout in milliseconds (used for HTTP request timeout and sent to API in seconds)
|
|
393
|
+
* @returns Execution result
|
|
384
394
|
*/
|
|
385
395
|
execute(command: string, options?: ExecuteOptions): Promise<ExecutionResult>;
|
|
386
396
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -44,11 +44,11 @@ declare class HTTPClient {
|
|
|
44
44
|
/**
|
|
45
45
|
* POST request with JSON body
|
|
46
46
|
*/
|
|
47
|
-
post<T = any>(url: string, data?: any, headers?: Record<string, string
|
|
47
|
+
post<T = any>(url: string, data?: any, headers?: Record<string, string>, timeout?: number): Promise<T>;
|
|
48
48
|
/**
|
|
49
49
|
* POST request for code execution (uses X-API-Key header like Python client)
|
|
50
50
|
*/
|
|
51
|
-
postExecution<T = any>(url: string, data: any, headers?: Record<string, string
|
|
51
|
+
postExecution<T = any>(url: string, data: any, headers?: Record<string, string>, timeout?: number): Promise<T>;
|
|
52
52
|
/**
|
|
53
53
|
* POST request with form data (for file uploads)
|
|
54
54
|
*/
|
|
@@ -360,6 +360,10 @@ interface DownloadResult {
|
|
|
360
360
|
|
|
361
361
|
interface InstaVMOptions {
|
|
362
362
|
baseURL?: string;
|
|
363
|
+
/**
|
|
364
|
+
* Timeout in milliseconds. Used for HTTP request timeout and sent to API as VM lifetime (in seconds).
|
|
365
|
+
* Default: 300000 (5 minutes)
|
|
366
|
+
*/
|
|
363
367
|
timeout?: number;
|
|
364
368
|
maxRetries?: number;
|
|
365
369
|
retryDelay?: number;
|
|
@@ -374,6 +378,7 @@ declare class InstaVM {
|
|
|
374
378
|
private _sessionId;
|
|
375
379
|
readonly browser: BrowserManager;
|
|
376
380
|
readonly local: boolean;
|
|
381
|
+
private readonly timeout;
|
|
377
382
|
constructor(apiKey: string, options?: InstaVMOptions);
|
|
378
383
|
/**
|
|
379
384
|
* Ensure operation is not called in local mode
|
|
@@ -381,6 +386,11 @@ declare class InstaVM {
|
|
|
381
386
|
private ensureNotLocal;
|
|
382
387
|
/**
|
|
383
388
|
* Execute code synchronously
|
|
389
|
+
*
|
|
390
|
+
* @param command - Command to execute
|
|
391
|
+
* @param options - Execution options
|
|
392
|
+
* @param options.timeout - Request timeout in milliseconds (used for HTTP request timeout and sent to API in seconds)
|
|
393
|
+
* @returns Execution result
|
|
384
394
|
*/
|
|
385
395
|
execute(command: string, options?: ExecuteOptions): Promise<ExecutionResult>;
|
|
386
396
|
/**
|
package/dist/index.js
CHANGED
|
@@ -278,18 +278,19 @@ var HTTPClient = class {
|
|
|
278
278
|
/**
|
|
279
279
|
* POST request with JSON body
|
|
280
280
|
*/
|
|
281
|
-
async post(url, data, headers) {
|
|
281
|
+
async post(url, data, headers, timeout) {
|
|
282
282
|
return this.request({
|
|
283
283
|
method: "POST",
|
|
284
284
|
url,
|
|
285
285
|
data,
|
|
286
|
-
headers
|
|
286
|
+
headers,
|
|
287
|
+
timeout
|
|
287
288
|
});
|
|
288
289
|
}
|
|
289
290
|
/**
|
|
290
291
|
* POST request for code execution (uses X-API-Key header like Python client)
|
|
291
292
|
*/
|
|
292
|
-
async postExecution(url, data, headers) {
|
|
293
|
+
async postExecution(url, data, headers, timeout) {
|
|
293
294
|
const requestHeaders = {
|
|
294
295
|
"X-API-Key": this.config.apiKey,
|
|
295
296
|
...headers
|
|
@@ -298,7 +299,8 @@ var HTTPClient = class {
|
|
|
298
299
|
method: "POST",
|
|
299
300
|
url,
|
|
300
301
|
data,
|
|
301
|
-
headers: requestHeaders
|
|
302
|
+
headers: requestHeaders,
|
|
303
|
+
timeout
|
|
302
304
|
});
|
|
303
305
|
}
|
|
304
306
|
/**
|
|
@@ -909,13 +911,13 @@ var InstaVM = class {
|
|
|
909
911
|
constructor(apiKey, options = {}) {
|
|
910
912
|
this._sessionId = null;
|
|
911
913
|
this.local = options.local || false;
|
|
914
|
+
this.timeout = options.timeout || 3e5;
|
|
912
915
|
if (!this.local && !apiKey) {
|
|
913
916
|
throw new AuthenticationError("API key is required for cloud mode");
|
|
914
917
|
}
|
|
915
918
|
const config = {
|
|
916
919
|
baseURL: this.local ? options.localURL || "http://coderunner.local:8222" : options.baseURL || "https://api.instavm.io",
|
|
917
|
-
timeout:
|
|
918
|
-
// 5 minutes
|
|
920
|
+
timeout: this.timeout,
|
|
919
921
|
maxRetries: options.maxRetries || 3,
|
|
920
922
|
retryDelay: options.retryDelay || 1e3,
|
|
921
923
|
apiKey: apiKey || ""
|
|
@@ -935,6 +937,11 @@ var InstaVM = class {
|
|
|
935
937
|
}
|
|
936
938
|
/**
|
|
937
939
|
* Execute code synchronously
|
|
940
|
+
*
|
|
941
|
+
* @param command - Command to execute
|
|
942
|
+
* @param options - Execution options
|
|
943
|
+
* @param options.timeout - Request timeout in milliseconds (used for HTTP request timeout and sent to API in seconds)
|
|
944
|
+
* @returns Execution result
|
|
938
945
|
*/
|
|
939
946
|
async execute(command, options = {}) {
|
|
940
947
|
let sessionId = options.sessionId || this._sessionId;
|
|
@@ -943,16 +950,21 @@ var InstaVM = class {
|
|
|
943
950
|
}
|
|
944
951
|
const requestData = {
|
|
945
952
|
command,
|
|
946
|
-
language: options.language || "python"
|
|
947
|
-
timeout: options.timeout || 15
|
|
953
|
+
language: options.language || "python"
|
|
948
954
|
};
|
|
955
|
+
if (options.timeout !== void 0) {
|
|
956
|
+
requestData.timeout = Math.floor(options.timeout / 1e3);
|
|
957
|
+
}
|
|
949
958
|
if (!this.local && sessionId) {
|
|
950
959
|
requestData.session_id = sessionId;
|
|
951
960
|
}
|
|
961
|
+
const requestTimeout = options.timeout !== void 0 ? options.timeout : this.timeout;
|
|
952
962
|
try {
|
|
953
963
|
const response = await this.httpClient.postExecution(
|
|
954
964
|
"/execute",
|
|
955
|
-
requestData
|
|
965
|
+
requestData,
|
|
966
|
+
void 0,
|
|
967
|
+
requestTimeout
|
|
956
968
|
);
|
|
957
969
|
if (response.session_id) {
|
|
958
970
|
this._sessionId = response.session_id;
|
|
@@ -1066,7 +1078,8 @@ var InstaVM = class {
|
|
|
1066
1078
|
this.ensureNotLocal("Session management");
|
|
1067
1079
|
try {
|
|
1068
1080
|
const response = await this.httpClient.post("/v1/sessions/session", {
|
|
1069
|
-
api_key: this.httpClient.apiKey
|
|
1081
|
+
api_key: this.httpClient.apiKey,
|
|
1082
|
+
vm_lifetime_seconds: Math.floor(this.timeout / 1e3)
|
|
1070
1083
|
});
|
|
1071
1084
|
if (response.session_id) {
|
|
1072
1085
|
this._sessionId = response.session_id;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/client/HTTPClient.ts","../src/errors/BaseError.ts","../src/utils/retry.ts","../src/client/BrowserSession.ts","../src/client/BrowserManager.ts","../src/client/InstaVM.ts"],"sourcesContent":["// Main client\nexport { InstaVM } from './client/InstaVM';\nexport type { InstaVMOptions } from './client/InstaVM';\n\n// Browser automation\nexport { BrowserManager } from './client/BrowserManager';\nexport { BrowserSession } from './client/BrowserSession';\n\n// Types\nexport type {\n ExecuteOptions,\n ExecutionResult,\n AsyncExecutionResult,\n FileUpload,\n UploadOptions,\n UploadResult,\n UsageStats,\n DownloadOptions,\n DownloadResult,\n} from './types/execution';\n\nexport type {\n BrowserSessionOptions,\n BrowserSessionInfo,\n NavigateOptions,\n NavigationResult,\n ClickOptions,\n TypeOptions,\n FillOptions,\n ScrollOptions,\n ScreenshotOptions,\n WaitCondition,\n ExtractedElement,\n ExtractOptions,\n ExtractContentOptions,\n ExtractedContent,\n InteractiveElement,\n ContentAnchor,\n} from './types/browser';\n\nexport type {\n ApiResponse,\n HttpClientConfig,\n RequestConfig,\n RetryConfig,\n} from './types/api';\n\n// Errors\nexport {\n InstaVMError,\n AuthenticationError,\n RateLimitError,\n QuotaExceededError,\n NetworkError,\n ExecutionError,\n SessionError,\n BrowserError,\n BrowserSessionError,\n BrowserInteractionError,\n BrowserTimeoutError,\n BrowserNavigationError,\n ElementNotFoundError,\n UnsupportedOperationError,\n} from './errors/BaseError';","import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';\nimport FormData from 'form-data';\nimport {\n InstaVMError,\n AuthenticationError,\n RateLimitError,\n QuotaExceededError,\n NetworkError,\n} from '../errors/BaseError';\nimport { withRetry } from '../utils/retry';\nimport type { HttpClientConfig, RequestConfig } from '../types/api';\n\n/**\n * HTTP client with authentication, retry logic, and error handling\n */\nexport class HTTPClient {\n private client: AxiosInstance;\n private config: HttpClientConfig;\n\n get apiKey(): string {\n return this.config.apiKey;\n }\n\n constructor(config: HttpClientConfig) {\n this.config = config;\n \n this.client = axios.create({\n baseURL: config.baseURL,\n timeout: config.timeout,\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'instavm-js-sdk/0.1.0',\n },\n });\n\n this.setupInterceptors();\n }\n\n private setupInterceptors(): void {\n // Request interceptor - add authentication\n this.client.interceptors.request.use(\n (config) => {\n // Add API key to headers for browser endpoints\n if (config.url?.includes('/browser/')) {\n config.headers['X-API-Key'] = this.config.apiKey;\n }\n \n return config;\n },\n (error) => Promise.reject(error)\n );\n\n // Response interceptor - handle errors\n this.client.interceptors.response.use(\n (response) => response,\n (error) => {\n const axiosError = error;\n const status = axiosError.response?.status;\n const data = axiosError.response?.data;\n const message = data?.message || data?.error || axiosError.message;\n\n switch (status) {\n case 401:\n throw new AuthenticationError(message, {\n statusCode: status,\n response: data,\n });\n case 402:\n throw new QuotaExceededError(message, {\n statusCode: status,\n response: data,\n });\n case 429:\n const retryAfter = parseInt(\n axiosError.response?.headers['retry-after'] || '60'\n );\n throw new RateLimitError(message, retryAfter, {\n statusCode: status,\n response: data,\n });\n case 500:\n case 502:\n case 503:\n case 504:\n throw new NetworkError(message, {\n statusCode: status,\n response: data,\n });\n default:\n if (axiosError.code === 'ECONNABORTED') {\n throw new NetworkError('Request timeout', {\n code: axiosError.code,\n });\n }\n throw new InstaVMError(message, {\n statusCode: status,\n response: data,\n code: axiosError.code,\n });\n }\n }\n );\n }\n\n /**\n * Make an HTTP request with retry logic\n */\n async request<T = any>(requestConfig: RequestConfig): Promise<T> {\n const axiosConfig: AxiosRequestConfig = {\n method: requestConfig.method,\n url: requestConfig.url,\n headers: requestConfig.headers,\n data: requestConfig.data,\n params: requestConfig.params,\n timeout: requestConfig.timeout || this.config.timeout,\n };\n\n const makeRequest = async (): Promise<T> => {\n const response: AxiosResponse<T> = await this.client.request(axiosConfig);\n return response.data;\n };\n\n return withRetry(makeRequest, {\n retries: this.config.maxRetries,\n retryDelay: this.config.retryDelay,\n });\n }\n\n /**\n * POST request with JSON body\n */\n async post<T = any>(\n url: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>({\n method: 'POST',\n url,\n data,\n headers,\n });\n }\n\n /**\n * POST request for code execution (uses X-API-Key header like Python client)\n */\n async postExecution<T = any>(\n url: string,\n data: any,\n headers?: Record<string, string>\n ): Promise<T> {\n const requestHeaders = {\n 'X-API-Key': this.config.apiKey,\n ...headers,\n };\n\n return this.request<T>({\n method: 'POST',\n url,\n data,\n headers: requestHeaders,\n });\n }\n\n /**\n * POST request with form data (for file uploads)\n */\n async postFormData<T = any>(\n url: string,\n formData: FormData,\n headers?: Record<string, string>\n ): Promise<T> {\n const requestHeaders = {\n ...formData.getHeaders(),\n ...headers,\n };\n\n return this.request<T>({\n method: 'POST',\n url,\n data: formData,\n headers: requestHeaders,\n });\n }\n\n /**\n * GET request\n */\n async get<T = any>(\n url: string,\n params?: Record<string, any>,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>({\n method: 'GET',\n url,\n params,\n headers,\n });\n }\n\n /**\n * DELETE request\n */\n async delete<T = any>(\n url: string,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>({\n method: 'DELETE',\n url,\n headers,\n });\n }\n\n /**\n * POST request that returns raw binary data (for file downloads)\n */\n async postRaw(\n url: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<ArrayBuffer> {\n const requestHeaders = {\n 'X-API-Key': this.config.apiKey,\n ...headers,\n };\n\n const axiosConfig: AxiosRequestConfig = {\n method: 'POST',\n url,\n data,\n headers: requestHeaders,\n responseType: 'arraybuffer',\n timeout: this.config.timeout,\n };\n\n const makeRequest = async (): Promise<ArrayBuffer> => {\n const response: AxiosResponse<ArrayBuffer> = await this.client.request(axiosConfig);\n return response.data;\n };\n\n return withRetry(makeRequest, {\n retries: this.config.maxRetries,\n retryDelay: this.config.retryDelay,\n });\n }\n}","/**\n * Base error class for all InstaVM SDK errors\n */\nexport class InstaVMError extends Error {\n public readonly name: string;\n public readonly code?: string;\n public readonly statusCode?: number;\n public readonly response?: any;\n\n constructor(\n message: string,\n options?: {\n code?: string;\n statusCode?: number;\n response?: any;\n cause?: Error;\n }\n ) {\n super(message);\n this.name = this.constructor.name;\n this.code = options?.code;\n this.statusCode = options?.statusCode;\n this.response = options?.response;\n\n // Ensure proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n\n // Capture stack trace, excluding constructor call from it\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Authentication-related errors (401, invalid API key, etc.)\n */\nexport class AuthenticationError extends InstaVMError {\n constructor(message: string = 'Authentication failed', options?: any) {\n super(message, { ...options, statusCode: 401 });\n }\n}\n\n/**\n * Rate limiting errors (429)\n */\nexport class RateLimitError extends InstaVMError {\n public readonly retryAfter?: number;\n\n constructor(\n message: string = 'Rate limit exceeded',\n retryAfter?: number,\n options?: any\n ) {\n super(message, { ...options, statusCode: 429 });\n this.retryAfter = retryAfter;\n }\n}\n\n/**\n * Quota/usage limit exceeded errors\n */\nexport class QuotaExceededError extends InstaVMError {\n constructor(message: string = 'Usage quota exceeded', options?: any) {\n super(message, { ...options, statusCode: 402 });\n }\n}\n\n/**\n * Network-related errors (timeouts, connection issues, 5xx errors)\n */\nexport class NetworkError extends InstaVMError {\n constructor(message: string = 'Network error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Code execution errors\n */\nexport class ExecutionError extends InstaVMError {\n public readonly executionOutput?: string;\n public readonly executionTime?: number;\n\n constructor(\n message: string,\n executionOutput?: string,\n executionTime?: number,\n options?: any\n ) {\n super(message, options);\n this.executionOutput = executionOutput;\n this.executionTime = executionTime;\n }\n}\n\n/**\n * Session management errors\n */\nexport class SessionError extends InstaVMError {\n constructor(message: string = 'Session error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser automation base error\n */\nexport class BrowserError extends InstaVMError {\n constructor(message: string = 'Browser error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser session management errors\n */\nexport class BrowserSessionError extends BrowserError {\n constructor(message: string = 'Browser session error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser interaction errors (click, type, etc.)\n */\nexport class BrowserInteractionError extends BrowserError {\n constructor(message: string = 'Browser interaction error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser timeout errors\n */\nexport class BrowserTimeoutError extends BrowserError {\n constructor(message: string = 'Browser operation timed out', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser navigation errors\n */\nexport class BrowserNavigationError extends BrowserError {\n constructor(message: string = 'Browser navigation error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Element not found errors\n */\nexport class ElementNotFoundError extends BrowserError {\n public readonly selector?: string;\n\n constructor(\n message: string = 'Element not found',\n selector?: string,\n options?: any\n ) {\n super(message, options);\n this.selector = selector;\n }\n}\n\n/**\n * Unsupported operation error (e.g., operations not available in local mode)\n */\nexport class UnsupportedOperationError extends InstaVMError {\n constructor(message: string = 'Operation not supported', options?: any) {\n super(message, options);\n }\n}","import { NetworkError, RateLimitError } from '../errors/BaseError';\n\nexport interface RetryOptions {\n retries: number;\n retryDelay: number;\n maxRetryDelay?: number;\n retryCondition?: (error: any) => boolean;\n}\n\n/**\n * Default retry condition - retry on network errors and 5xx server errors\n */\nexport function defaultRetryCondition(error: any): boolean {\n if (error instanceof NetworkError) return true;\n if (error instanceof RateLimitError) return true;\n \n // Axios error with status code\n if (error.response?.status >= 500) return true;\n \n // Network/timeout errors\n if (error.code === 'ECONNABORTED' || error.code === 'ETIMEDOUT') return true;\n if (error.code === 'ECONNRESET' || error.code === 'ENOTFOUND') return true;\n \n return false;\n}\n\n/**\n * Calculate exponential backoff delay\n */\nexport function calculateRetryDelay(\n attempt: number,\n baseDelay: number,\n maxDelay = 30000\n): number {\n const exponentialDelay = baseDelay * Math.pow(2, attempt - 1);\n const jitteredDelay = exponentialDelay * (0.5 + Math.random() * 0.5);\n return Math.min(jitteredDelay, maxDelay);\n}\n\n/**\n * Retry a function with exponential backoff\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions\n): Promise<T> {\n const {\n retries,\n retryDelay,\n maxRetryDelay = 30000,\n retryCondition = defaultRetryCondition,\n } = options;\n\n let lastError: any;\n\n for (let attempt = 1; attempt <= retries + 1; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n\n // Don't retry on last attempt\n if (attempt === retries + 1) {\n break;\n }\n\n // Check if we should retry this error\n if (!retryCondition(error)) {\n break;\n }\n\n // Calculate delay for this attempt\n const delay = calculateRetryDelay(attempt, retryDelay, maxRetryDelay);\n \n // Wait before retrying\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n\n throw lastError;\n}","import { EventEmitter } from 'eventemitter3';\nimport type { HTTPClient } from './HTTPClient';\nimport {\n BrowserError,\n BrowserInteractionError,\n BrowserNavigationError,\n BrowserTimeoutError,\n ElementNotFoundError,\n} from '../errors/BaseError';\nimport type {\n NavigateOptions,\n NavigationResult,\n ClickOptions,\n TypeOptions,\n FillOptions,\n ScrollOptions,\n ScreenshotOptions,\n WaitCondition,\n ExtractedElement,\n ExtractOptions,\n ExtractContentOptions,\n ExtractedContent,\n} from '../types/browser';\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * Browser session for automation\n */\nexport class BrowserSession extends EventEmitter {\n public readonly sessionId: string;\n private httpClient: HTTPClient;\n private _isActive: boolean = true;\n\n constructor(sessionId: string, httpClient: HTTPClient) {\n super();\n this.sessionId = sessionId;\n this.httpClient = httpClient;\n }\n\n /**\n * Navigate to a URL\n */\n async navigate(\n url: string,\n options: NavigateOptions = {}\n ): Promise<NavigationResult> {\n this.ensureActive();\n\n const requestData = {\n url,\n session_id: this.sessionId,\n wait_timeout: options.waitTimeout || 30000,\n wait_until: options.waitUntil || 'load',\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/navigate',\n requestData\n );\n\n const result: NavigationResult = {\n success: response.success !== false,\n url: response.url || url,\n title: response.title,\n status: response.status,\n };\n\n this.emit('navigation', result);\n return result;\n } catch (error) {\n const navigationError = new BrowserNavigationError(\n `Navigation failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n this.emit('error', navigationError);\n throw navigationError;\n }\n }\n\n /**\n * Click an element\n */\n async click(selector: string, options: ClickOptions = {}): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n selector,\n session_id: this.sessionId,\n timeout: options.timeout || 10000,\n button: options.button || 'left',\n click_count: options.clickCount || 1,\n force: options.force || false,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/click',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('not found') || errorMessage.includes('selector')) {\n throw new ElementNotFoundError(\n `Element not found: ${selector}`,\n selector,\n { cause: error as Error }\n );\n }\n if (errorMessage.includes('timeout')) {\n throw new BrowserTimeoutError(\n `Click timeout: ${selector}`,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Click failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Type text into an element\n */\n async type(\n selector: string,\n text: string,\n options: TypeOptions = {}\n ): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n selector,\n text,\n session_id: this.sessionId,\n timeout: options.timeout || 10000,\n delay: options.delay || 0,\n clear: options.clear !== false,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/type',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('not found') || errorMessage.includes('selector')) {\n throw new ElementNotFoundError(\n `Element not found: ${selector}`,\n selector,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Type failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Fill a form field\n */\n async fill(\n selector: string,\n value: string,\n options: FillOptions = {}\n ): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n selector,\n value,\n session_id: this.sessionId,\n timeout: options.timeout || 10000,\n force: options.force || false,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/fill',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('not found') || errorMessage.includes('selector')) {\n throw new ElementNotFoundError(\n `Element not found: ${selector}`,\n selector,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Fill failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Scroll the page\n */\n async scroll(options: ScrollOptions = {}): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n session_id: this.sessionId,\n x: options.x || 0,\n y: options.y || 500,\n behavior: options.behavior || 'auto',\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/scroll',\n requestData\n );\n } catch (error) {\n throw new BrowserInteractionError(\n `Scroll failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Take a screenshot\n */\n async screenshot(options: ScreenshotOptions = {}): Promise<string> {\n this.ensureActive();\n\n const requestData = {\n session_id: this.sessionId,\n full_page: options.fullPage !== false,\n format: options.format || 'png',\n quality: options.quality || 90,\n clip: options.clip,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/screenshot',\n requestData\n );\n\n if (!response.screenshot) {\n throw new BrowserError('Screenshot data not returned');\n }\n\n return response.screenshot;\n } catch (error) {\n throw new BrowserInteractionError(\n `Screenshot failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Extract elements from the page\n */\n async extractElements(\n selector: string,\n attributes: string[] = ['text'],\n options: ExtractOptions = {}\n ): Promise<ExtractedElement[]> {\n this.ensureActive();\n\n const requestData = {\n selector,\n attributes,\n session_id: this.sessionId,\n max_results: options.maxResults || 100,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/extract',\n requestData\n );\n\n return response.elements || [];\n } catch (error) {\n throw new BrowserInteractionError(\n `Element extraction failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Extract LLM-friendly content from the current page\n *\n * Returns clean article content, interactive elements, and content anchors\n * for intelligent browser automation with LLMs.\n *\n * @param options - Content extraction options\n * @returns Extracted content with readable text, interactive elements, and content anchors\n *\n * @example\n * ```typescript\n * const content = await session.extractContent();\n *\n * // LLM reads clean content\n * const article = content.readableContent.content;\n *\n * // LLM finds \"Sign Up\" in content and uses anchors to get selector\n * const signUpAnchor = content.contentAnchors?.find(\n * anchor => anchor.text.toLowerCase().includes('sign up')\n * );\n * if (signUpAnchor) {\n * await session.click(signUpAnchor.selector);\n * }\n * ```\n */\n async extractContent(\n options: ExtractContentOptions = {}\n ): Promise<ExtractedContent> {\n this.ensureActive();\n\n const requestData = {\n session_id: this.sessionId,\n include_interactive: options.includeInteractive !== false,\n include_anchors: options.includeAnchors !== false,\n max_anchors: options.maxAnchors ?? 50,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/content',\n requestData\n );\n\n return {\n readableContent: {\n ...(response.readable_content || {}),\n content: response.readable_content?.content || '',\n },\n interactiveElements: response.interactive_elements,\n contentAnchors: response.content_anchors,\n };\n } catch (error) {\n throw new BrowserInteractionError(\n `Content extraction failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Wait for a condition\n */\n async wait(condition: WaitCondition, timeout = 10000): Promise<void> {\n this.ensureActive();\n\n let requestData: any = {\n session_id: this.sessionId,\n timeout,\n };\n\n if (condition.type === 'timeout') {\n // Simple timeout wait\n await new Promise(resolve => setTimeout(resolve, condition.ms));\n return;\n }\n\n requestData = {\n ...requestData,\n condition: condition.type,\n selector: 'selector' in condition ? condition.selector : undefined,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/wait',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('timeout')) {\n throw new BrowserTimeoutError(\n `Wait condition timeout: ${condition.type}`,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Wait failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Close the browser session\n */\n async close(): Promise<void> {\n if (!this._isActive) {\n return;\n }\n\n try {\n await this.httpClient.delete(`/v1/browser/sessions/${this.sessionId}`);\n } catch (error) {\n // Don't throw on close errors - session might already be closed\n console.warn(`Failed to close browser session ${this.sessionId}:`, getErrorMessage(error));\n } finally {\n this._isActive = false;\n this.emit('close');\n }\n }\n\n /**\n * Check if session is active\n */\n get isActive(): boolean {\n return this._isActive;\n }\n\n /**\n * Ensure session is active before operations\n */\n private ensureActive(): void {\n if (!this._isActive) {\n throw new BrowserError('Browser session is not active');\n }\n }\n}","import type { HTTPClient } from './HTTPClient';\nimport { BrowserSession } from './BrowserSession';\nimport { BrowserSessionError, BrowserNavigationError, BrowserInteractionError, UnsupportedOperationError } from '../errors/BaseError';\nimport type {\n BrowserSessionOptions,\n BrowserSessionInfo,\n NavigateOptions,\n NavigationResult,\n ExtractContentOptions,\n ExtractedContent,\n} from '../types/browser';\n\n/**\n * Browser automation manager\n */\nexport class BrowserManager {\n private httpClient: HTTPClient;\n private activeSessions: Map<string, BrowserSession> = new Map();\n private local: boolean;\n\n constructor(httpClient: HTTPClient, local: boolean = false) {\n this.httpClient = httpClient;\n this.local = local;\n }\n\n /**\n * Create a new browser session\n */\n async createSession(\n options: BrowserSessionOptions = {}\n ): Promise<BrowserSession> {\n if (this.local) {\n throw new UnsupportedOperationError(\n 'Browser session management is not supported in local mode. Use navigate() or extractContent() with URL directly.'\n );\n }\n\n const requestData = {\n viewport_width: options.viewportWidth || 1920,\n viewport_height: options.viewportHeight || 1080,\n user_agent: options.userAgent,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/sessions/',\n requestData\n );\n\n if (!response.session_id) {\n throw new BrowserSessionError('No session ID returned from server');\n }\n\n const session = new BrowserSession(response.session_id, this.httpClient);\n this.activeSessions.set(response.session_id, session);\n\n // Clean up session from our tracking when it's closed\n session.on('close', () => {\n this.activeSessions.delete(response.session_id);\n });\n\n return session;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserSessionError(\n `Failed to create browser session: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Get information about a specific session\n */\n async getSession(sessionId: string): Promise<BrowserSessionInfo> {\n try {\n const response = await this.httpClient.get<any>(\n `/v1/browser/sessions/${sessionId}`\n );\n\n return {\n sessionId: response.session_id,\n status: response.status || 'active',\n createdAt: response.created_at,\n viewportWidth: response.viewport_width,\n viewportHeight: response.viewport_height,\n userAgent: response.user_agent,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserSessionError(\n `Failed to get session info: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * List all browser sessions\n */\n async listSessions(): Promise<BrowserSessionInfo[]> {\n try {\n const response = await this.httpClient.get<any>('/v1/browser/sessions/');\n\n if (!Array.isArray(response.sessions)) {\n return [];\n }\n\n return response.sessions.map((session: any) => ({\n sessionId: session.session_id,\n status: session.status || 'active',\n createdAt: session.created_at,\n viewportWidth: session.viewport_width,\n viewportHeight: session.viewport_height,\n userAgent: session.user_agent,\n }));\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserSessionError(\n `Failed to list sessions: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Get a locally tracked session\n */\n getLocalSession(sessionId: string): BrowserSession | undefined {\n return this.activeSessions.get(sessionId);\n }\n\n /**\n * Get all locally tracked sessions\n */\n getLocalSessions(): BrowserSession[] {\n return Array.from(this.activeSessions.values());\n }\n\n /**\n * Close all active sessions\n */\n async closeAllSessions(): Promise<void> {\n const sessions = Array.from(this.activeSessions.values());\n \n await Promise.allSettled(\n sessions.map(session => session.close())\n );\n \n this.activeSessions.clear();\n }\n\n /**\n * Navigate to a URL (local mode support - no session required)\n */\n async navigate(\n url: string,\n options: NavigateOptions = {}\n ): Promise<NavigationResult> {\n if (!this.local) {\n throw new UnsupportedOperationError(\n 'navigate() without session is only supported in local mode. In cloud mode, create a session first.'\n );\n }\n\n const requestData = {\n url,\n wait_timeout: options.waitTimeout || 30000,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/navigate',\n requestData\n );\n\n return {\n success: response.success !== false,\n url: response.url || url,\n title: response.title,\n status: response.status,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserNavigationError(\n `Navigation failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Extract LLM-friendly content (local mode support - no session required)\n */\n async extractContent(\n options: ExtractContentOptions = {}\n ): Promise<ExtractedContent> {\n if (!this.local) {\n throw new UnsupportedOperationError(\n 'extractContent() without session is only supported in local mode. In cloud mode, create a session first.'\n );\n }\n\n if (!options.url) {\n throw new BrowserInteractionError('url is required in local mode');\n }\n\n const requestData = {\n url: options.url,\n include_interactive: options.includeInteractive !== false,\n include_anchors: options.includeAnchors !== false,\n max_anchors: options.maxAnchors ?? 50,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/content',\n requestData\n );\n\n return {\n readableContent: {\n ...(response.readable_content || {}),\n content: response.readable_content?.content || '',\n },\n interactiveElements: response.interactive_elements,\n contentAnchors: response.content_anchors,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserInteractionError(\n `Content extraction failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Clean up resources\n */\n async dispose(): Promise<void> {\n await this.closeAllSessions();\n }\n}","import { HTTPClient } from './HTTPClient';\nimport { BrowserManager } from './BrowserManager';\nimport FormData from 'form-data';\nimport { SessionError, ExecutionError, UnsupportedOperationError, AuthenticationError } from '../errors/BaseError';\nimport type {\n ExecuteOptions,\n ExecutionResult,\n AsyncExecutionResult,\n FileUpload,\n UploadOptions,\n UploadResult,\n UsageStats,\n DownloadOptions,\n DownloadResult,\n} from '../types/execution';\n\nexport interface InstaVMOptions {\n baseURL?: string;\n timeout?: number;\n maxRetries?: number;\n retryDelay?: number;\n local?: boolean;\n localURL?: string;\n}\n\n/**\n * Main InstaVM client class\n */\nexport class InstaVM {\n private httpClient: HTTPClient;\n private _sessionId: string | null = null;\n public readonly browser: BrowserManager;\n public readonly local: boolean;\n\n constructor(apiKey: string, options: InstaVMOptions = {}) {\n this.local = options.local || false;\n\n // In local mode, API key is optional\n if (!this.local && !apiKey) {\n throw new AuthenticationError('API key is required for cloud mode');\n }\n\n const config = {\n baseURL: this.local\n ? (options.localURL || 'http://coderunner.local:8222')\n : (options.baseURL || 'https://api.instavm.io'),\n timeout: options.timeout || 300000, // 5 minutes\n maxRetries: options.maxRetries || 3,\n retryDelay: options.retryDelay || 1000,\n apiKey: apiKey || '',\n };\n\n this.httpClient = new HTTPClient(config);\n this.browser = new BrowserManager(this.httpClient, this.local);\n }\n\n /**\n * Ensure operation is not called in local mode\n */\n private ensureNotLocal(operationName: string): void {\n if (this.local) {\n throw new UnsupportedOperationError(\n `${operationName} is not supported in local mode. This operation is only available when using the cloud API.`\n );\n }\n }\n\n /**\n * Execute code synchronously\n */\n async execute(\n command: string,\n options: ExecuteOptions = {}\n ): Promise<ExecutionResult> {\n // In local mode, session_id is not required\n let sessionId = options.sessionId || this._sessionId;\n if (!this.local && !sessionId) {\n sessionId = await this.createSession();\n }\n\n const requestData: any = {\n command,\n language: options.language || 'python',\n timeout: options.timeout || 15,\n };\n\n // Only include session_id in cloud mode\n if (!this.local && sessionId) {\n requestData.session_id = sessionId;\n }\n\n try {\n const response = await this.httpClient.postExecution<any>(\n '/execute',\n requestData\n );\n\n // Update session ID if returned\n if (response.session_id) {\n this._sessionId = response.session_id;\n }\n\n return {\n output: response.stdout || response.output || '',\n success: response.success !== false,\n executionTime: response.execution_time || 0,\n sessionId: response.session_id,\n error: response.error,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new ExecutionError(\n `Code execution failed: ${errorMessage}`,\n undefined,\n undefined,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Execute code asynchronously\n */\n async executeAsync(\n command: string,\n options: ExecuteOptions = {}\n ): Promise<AsyncExecutionResult> {\n this.ensureNotLocal('Async execution');\n\n // Auto-create session if none exists (like Python client)\n let sessionId = options.sessionId || this._sessionId;\n if (!sessionId) {\n sessionId = await this.createSession();\n }\n\n const requestData = {\n command,\n language: options.language || 'python',\n timeout: options.timeout || 15,\n session_id: sessionId,\n };\n\n try {\n const response = await this.httpClient.postExecution<any>(\n '/execute_async',\n requestData\n );\n\n // Update session ID if returned\n if (response.session_id) {\n this._sessionId = response.session_id;\n }\n\n return {\n taskId: response.task_id,\n status: response.status || 'pending',\n output: response.stdout || response.output,\n success: response.success,\n executionTime: response.execution_time,\n sessionId: response.session_id,\n error: response.error,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new ExecutionError(\n `Async code execution failed: ${errorMessage}`,\n undefined,\n undefined,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Upload files to the execution environment\n */\n async upload(\n files: FileUpload[],\n options: UploadOptions = {}\n ): Promise<UploadResult> {\n this.ensureNotLocal('File upload');\n const formData = new FormData();\n\n // Add files to form data\n for (const file of files) {\n if (Buffer.isBuffer(file.content)) {\n formData.append('files', file.content, file.name);\n } else {\n formData.append('files', Buffer.from(file.content), file.name);\n }\n \n if (file.path) {\n formData.append('paths', file.path);\n }\n }\n\n // Add options\n if (options.sessionId || this._sessionId) {\n formData.append('session_id', options.sessionId || this._sessionId!);\n }\n if (options.remotePath) {\n formData.append('remote_path', options.remotePath);\n }\n if (options.recursive !== undefined) {\n formData.append('recursive', String(options.recursive));\n }\n\n try {\n const response = await this.httpClient.postFormData<any>(\n '/upload',\n formData\n );\n\n return {\n success: response.success !== false,\n files: response.files || [],\n message: response.message,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `File upload failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Create a new execution session\n */\n async createSession(): Promise<string> {\n this.ensureNotLocal('Session management');\n\n try {\n // Send API key in JSON body for session creation (like Python client)\n const response = await this.httpClient.post<any>('/v1/sessions/session', {\n api_key: this.httpClient.apiKey\n });\n\n if (response.session_id) {\n this._sessionId = response.session_id;\n return response.session_id;\n }\n\n throw new SessionError('Session creation failed: No session ID returned');\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `Session creation failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Close a session\n */\n async closeSession(sessionId?: string): Promise<void> {\n const targetSessionId = sessionId || this._sessionId;\n \n if (!targetSessionId) {\n return; // No session to close\n }\n\n try {\n await this.httpClient.delete(`/v1/sessions/${targetSessionId}`);\n \n if (targetSessionId === this._sessionId) {\n this._sessionId = null;\n }\n } catch (error) {\n // Don't throw on session close errors - session might already be expired\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.warn(`Failed to close session ${targetSessionId}:`, errorMessage);\n }\n }\n\n /**\n * Get usage statistics for a session\n */\n async getUsage(sessionId?: string): Promise<UsageStats> {\n this.ensureNotLocal('Usage tracking');\n\n const targetSessionId = sessionId || this._sessionId;\n\n if (!targetSessionId) {\n throw new SessionError('No active session to get usage for');\n }\n\n try {\n const response = await this.httpClient.get<any>(\n `/v1/sessions/usage/${targetSessionId}`\n );\n\n return {\n sessionsUsed: response.sessions_used || 0,\n executionTime: response.execution_time || 0,\n quotaRemaining: response.quota_remaining || 0,\n quotaLimit: response.quota_limit || 0,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `Failed to get usage stats: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Download a file from the remote VM\n */\n async download(\n filename: string,\n options: DownloadOptions = {}\n ): Promise<DownloadResult> {\n this.ensureNotLocal('File download');\n\n const targetSessionId = options.sessionId || this._sessionId;\n\n if (!targetSessionId) {\n throw new SessionError('No active session to download from');\n }\n\n try {\n const response = await this.httpClient.postRaw('/download', {\n filename,\n session_id: targetSessionId,\n });\n\n const content = Buffer.from(response);\n\n return {\n success: true,\n filename,\n content,\n size: content.length,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `File download failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Get the current session ID\n */\n get sessionId(): string | null {\n return this._sessionId;\n }\n\n /**\n * Clean up resources\n */\n async dispose(): Promise<void> {\n if (this._sessionId) {\n await this.closeSession();\n }\n await this.browser.dispose();\n }\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAAwE;;;ACGjE,IAAM,eAAN,cAA2B,MAAM;AAAA,EAMtC,YACE,SACA,SAMA;AACA,UAAM,OAAO;AACb,SAAK,OAAO,KAAK,YAAY;AAC7B,SAAK,OAAO,SAAS;AACrB,SAAK,aAAa,SAAS;AAC3B,SAAK,WAAW,SAAS;AAGzB,WAAO,eAAe,MAAM,WAAW,SAAS;AAGhD,QAAI,MAAM,mBAAmB;AAC3B,YAAM,kBAAkB,MAAM,KAAK,WAAW;AAAA,IAChD;AAAA,EACF;AACF;AAKO,IAAM,sBAAN,cAAkC,aAAa;AAAA,EACpD,YAAY,UAAkB,yBAAyB,SAAe;AACpE,UAAM,SAAS,EAAE,GAAG,SAAS,YAAY,IAAI,CAAC;AAAA,EAChD;AACF;AAKO,IAAM,iBAAN,cAA6B,aAAa;AAAA,EAG/C,YACE,UAAkB,uBAClB,YACA,SACA;AACA,UAAM,SAAS,EAAE,GAAG,SAAS,YAAY,IAAI,CAAC;AAC9C,SAAK,aAAa;AAAA,EACpB;AACF;AAKO,IAAM,qBAAN,cAAiC,aAAa;AAAA,EACnD,YAAY,UAAkB,wBAAwB,SAAe;AACnE,UAAM,SAAS,EAAE,GAAG,SAAS,YAAY,IAAI,CAAC;AAAA,EAChD;AACF;AAKO,IAAM,eAAN,cAA2B,aAAa;AAAA,EAC7C,YAAY,UAAkB,iBAAiB,SAAe;AAC5D,UAAM,SAAS,OAAO;AAAA,EACxB;AACF;AAKO,IAAM,iBAAN,cAA6B,aAAa;AAAA,EAI/C,YACE,SACA,iBACA,eACA,SACA;AACA,UAAM,SAAS,OAAO;AACtB,SAAK,kBAAkB;AACvB,SAAK,gBAAgB;AAAA,EACvB;AACF;AAKO,IAAM,eAAN,cAA2B,aAAa;AAAA,EAC7C,YAAY,UAAkB,iBAAiB,SAAe;AAC5D,UAAM,SAAS,OAAO;AAAA,EACxB;AACF;AAKO,IAAM,eAAN,cAA2B,aAAa;AAAA,EAC7C,YAAY,UAAkB,iBAAiB,SAAe;AAC5D,UAAM,SAAS,OAAO;AAAA,EACxB;AACF;AAKO,IAAM,sBAAN,cAAkC,aAAa;AAAA,EACpD,YAAY,UAAkB,yBAAyB,SAAe;AACpE,UAAM,SAAS,OAAO;AAAA,EACxB;AACF;AAKO,IAAM,0BAAN,cAAsC,aAAa;AAAA,EACxD,YAAY,UAAkB,6BAA6B,SAAe;AACxE,UAAM,SAAS,OAAO;AAAA,EACxB;AACF;AAKO,IAAM,sBAAN,cAAkC,aAAa;AAAA,EACpD,YAAY,UAAkB,+BAA+B,SAAe;AAC1E,UAAM,SAAS,OAAO;AAAA,EACxB;AACF;AAKO,IAAM,yBAAN,cAAqC,aAAa;AAAA,EACvD,YAAY,UAAkB,4BAA4B,SAAe;AACvE,UAAM,SAAS,OAAO;AAAA,EACxB;AACF;AAKO,IAAM,uBAAN,cAAmC,aAAa;AAAA,EAGrD,YACE,UAAkB,qBAClB,UACA,SACA;AACA,UAAM,SAAS,OAAO;AACtB,SAAK,WAAW;AAAA,EAClB;AACF;AAKO,IAAM,4BAAN,cAAwC,aAAa;AAAA,EAC1D,YAAY,UAAkB,2BAA2B,SAAe;AACtE,UAAM,SAAS,OAAO;AAAA,EACxB;AACF;;;ACjKO,SAAS,sBAAsB,OAAqB;AACzD,MAAI,iBAAiB,aAAc,QAAO;AAC1C,MAAI,iBAAiB,eAAgB,QAAO;AAG5C,MAAI,MAAM,UAAU,UAAU,IAAK,QAAO;AAG1C,MAAI,MAAM,SAAS,kBAAkB,MAAM,SAAS,YAAa,QAAO;AACxE,MAAI,MAAM,SAAS,gBAAgB,MAAM,SAAS,YAAa,QAAO;AAEtE,SAAO;AACT;AAKO,SAAS,oBACd,SACA,WACA,WAAW,KACH;AACR,QAAM,mBAAmB,YAAY,KAAK,IAAI,GAAG,UAAU,CAAC;AAC5D,QAAM,gBAAgB,oBAAoB,MAAM,KAAK,OAAO,IAAI;AAChE,SAAO,KAAK,IAAI,eAAe,QAAQ;AACzC;AAKA,eAAsB,UACpB,IACA,SACY;AACZ,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,EACnB,IAAI;AAEJ,MAAI;AAEJ,WAAS,UAAU,GAAG,WAAW,UAAU,GAAG,WAAW;AACvD,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,SAAS,OAAO;AACd,kBAAY;AAGZ,UAAI,YAAY,UAAU,GAAG;AAC3B;AAAA,MACF;AAGA,UAAI,CAAC,eAAe,KAAK,GAAG;AAC1B;AAAA,MACF;AAGA,YAAM,QAAQ,oBAAoB,SAAS,YAAY,aAAa;AAGpE,YAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,KAAK,CAAC;AAAA,IACzD;AAAA,EACF;AAEA,QAAM;AACR;;;AFjEO,IAAM,aAAN,MAAiB;AAAA,EAItB,IAAI,SAAiB;AACnB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,YAAY,QAA0B;AACpC,SAAK,SAAS;AAEd,SAAK,SAAS,aAAAA,QAAM,OAAO;AAAA,MACzB,SAAS,OAAO;AAAA,MAChB,SAAS,OAAO;AAAA,MAChB,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,cAAc;AAAA,MAChB;AAAA,IACF,CAAC;AAED,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEQ,oBAA0B;AAEhC,SAAK,OAAO,aAAa,QAAQ;AAAA,MAC/B,CAAC,WAAW;AAEV,YAAI,OAAO,KAAK,SAAS,WAAW,GAAG;AACrC,iBAAO,QAAQ,WAAW,IAAI,KAAK,OAAO;AAAA,QAC5C;AAEA,eAAO;AAAA,MACT;AAAA,MACA,CAAC,UAAU,QAAQ,OAAO,KAAK;AAAA,IACjC;AAGA,SAAK,OAAO,aAAa,SAAS;AAAA,MAChC,CAAC,aAAa;AAAA,MACd,CAAC,UAAU;AACT,cAAM,aAAa;AACnB,cAAM,SAAS,WAAW,UAAU;AACpC,cAAM,OAAO,WAAW,UAAU;AAClC,cAAM,UAAU,MAAM,WAAW,MAAM,SAAS,WAAW;AAE3D,gBAAQ,QAAQ;AAAA,UACd,KAAK;AACH,kBAAM,IAAI,oBAAoB,SAAS;AAAA,cACrC,YAAY;AAAA,cACZ,UAAU;AAAA,YACZ,CAAC;AAAA,UACH,KAAK;AACH,kBAAM,IAAI,mBAAmB,SAAS;AAAA,cACpC,YAAY;AAAA,cACZ,UAAU;AAAA,YACZ,CAAC;AAAA,UACH,KAAK;AACH,kBAAM,aAAa;AAAA,cACjB,WAAW,UAAU,QAAQ,aAAa,KAAK;AAAA,YACjD;AACA,kBAAM,IAAI,eAAe,SAAS,YAAY;AAAA,cAC5C,YAAY;AAAA,cACZ,UAAU;AAAA,YACZ,CAAC;AAAA,UACH,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AACH,kBAAM,IAAI,aAAa,SAAS;AAAA,cAC9B,YAAY;AAAA,cACZ,UAAU;AAAA,YACZ,CAAC;AAAA,UACH;AACE,gBAAI,WAAW,SAAS,gBAAgB;AACtC,oBAAM,IAAI,aAAa,mBAAmB;AAAA,gBACxC,MAAM,WAAW;AAAA,cACnB,CAAC;AAAA,YACH;AACA,kBAAM,IAAI,aAAa,SAAS;AAAA,cAC9B,YAAY;AAAA,cACZ,UAAU;AAAA,cACV,MAAM,WAAW;AAAA,YACnB,CAAC;AAAA,QACL;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAiB,eAA0C;AAC/D,UAAM,cAAkC;AAAA,MACtC,QAAQ,cAAc;AAAA,MACtB,KAAK,cAAc;AAAA,MACnB,SAAS,cAAc;AAAA,MACvB,MAAM,cAAc;AAAA,MACpB,QAAQ,cAAc;AAAA,MACtB,SAAS,cAAc,WAAW,KAAK,OAAO;AAAA,IAChD;AAEA,UAAM,cAAc,YAAwB;AAC1C,YAAM,WAA6B,MAAM,KAAK,OAAO,QAAQ,WAAW;AACxE,aAAO,SAAS;AAAA,IAClB;AAEA,WAAO,UAAU,aAAa;AAAA,MAC5B,SAAS,KAAK,OAAO;AAAA,MACrB,YAAY,KAAK,OAAO;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KACJ,KACA,MACA,SACY;AACZ,WAAO,KAAK,QAAW;AAAA,MACrB,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cACJ,KACA,MACA,SACY;AACZ,UAAM,iBAAiB;AAAA,MACrB,aAAa,KAAK,OAAO;AAAA,MACzB,GAAG;AAAA,IACL;AAEA,WAAO,KAAK,QAAW;AAAA,MACrB,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aACJ,KACA,UACA,SACY;AACZ,UAAM,iBAAiB;AAAA,MACrB,GAAG,SAAS,WAAW;AAAA,MACvB,GAAG;AAAA,IACL;AAEA,WAAO,KAAK,QAAW;AAAA,MACrB,QAAQ;AAAA,MACR;AAAA,MACA,MAAM;AAAA,MACN,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IACJ,KACA,QACA,SACY;AACZ,WAAO,KAAK,QAAW;AAAA,MACrB,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OACJ,KACA,SACY;AACZ,WAAO,KAAK,QAAW;AAAA,MACrB,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QACJ,KACA,MACA,SACsB;AACtB,UAAM,iBAAiB;AAAA,MACrB,aAAa,KAAK,OAAO;AAAA,MACzB,GAAG;AAAA,IACL;AAEA,UAAM,cAAkC;AAAA,MACtC,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT,cAAc;AAAA,MACd,SAAS,KAAK,OAAO;AAAA,IACvB;AAEA,UAAM,cAAc,YAAkC;AACpD,YAAM,WAAuC,MAAM,KAAK,OAAO,QAAQ,WAAW;AAClF,aAAO,SAAS;AAAA,IAClB;AAEA,WAAO,UAAU,aAAa;AAAA,MAC5B,SAAS,KAAK,OAAO;AAAA,MACrB,YAAY,KAAK,OAAO;AAAA,IAC1B,CAAC;AAAA,EACH;AACF;;;AGxPA,2BAA6B;AAwB7B,SAAS,gBAAgB,OAAwB;AAC/C,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAKO,IAAM,iBAAN,cAA6B,kCAAa;AAAA,EAK/C,YAAY,WAAmB,YAAwB;AACrD,UAAM;AAHR,SAAQ,YAAqB;AAI3B,SAAK,YAAY;AACjB,SAAK,aAAa;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SACJ,KACA,UAA2B,CAAC,GACD;AAC3B,SAAK,aAAa;AAElB,UAAM,cAAc;AAAA,MAClB;AAAA,MACA,YAAY,KAAK;AAAA,MACjB,cAAc,QAAQ,eAAe;AAAA,MACrC,YAAY,QAAQ,aAAa;AAAA,IACnC;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW;AAAA,QACrC;AAAA,QACA;AAAA,MACF;AAEA,YAAM,SAA2B;AAAA,QAC/B,SAAS,SAAS,YAAY;AAAA,QAC9B,KAAK,SAAS,OAAO;AAAA,QACrB,OAAO,SAAS;AAAA,QAChB,QAAQ,SAAS;AAAA,MACnB;AAEA,WAAK,KAAK,cAAc,MAAM;AAC9B,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,kBAAkB,IAAI;AAAA,QAC1B,sBAAsB,gBAAgB,KAAK,CAAC;AAAA,QAC5C,EAAE,OAAO,MAAe;AAAA,MAC1B;AACA,WAAK,KAAK,SAAS,eAAe;AAClC,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAM,UAAkB,UAAwB,CAAC,GAAkB;AACvE,SAAK,aAAa;AAElB,UAAM,cAAc;AAAA,MAClB;AAAA,MACA,YAAY,KAAK;AAAA,MACjB,SAAS,QAAQ,WAAW;AAAA,MAC5B,QAAQ,QAAQ,UAAU;AAAA,MAC1B,aAAa,QAAQ,cAAc;AAAA,MACnC,OAAO,QAAQ,SAAS;AAAA,IAC1B;AAEA,QAAI;AACF,YAAM,KAAK,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eAAe,gBAAgB,KAAK;AAC1C,UAAI,aAAa,SAAS,WAAW,KAAK,aAAa,SAAS,UAAU,GAAG;AAC3E,cAAM,IAAI;AAAA,UACR,sBAAsB,QAAQ;AAAA,UAC9B;AAAA,UACA,EAAE,OAAO,MAAe;AAAA,QAC1B;AAAA,MACF;AACA,UAAI,aAAa,SAAS,SAAS,GAAG;AACpC,cAAM,IAAI;AAAA,UACR,kBAAkB,QAAQ;AAAA,UAC1B,EAAE,OAAO,MAAe;AAAA,QAC1B;AAAA,MACF;AACA,YAAM,IAAI;AAAA,QACR,iBAAiB,YAAY;AAAA,QAC7B,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KACJ,UACA,MACA,UAAuB,CAAC,GACT;AACf,SAAK,aAAa;AAElB,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA,YAAY,KAAK;AAAA,MACjB,SAAS,QAAQ,WAAW;AAAA,MAC5B,OAAO,QAAQ,SAAS;AAAA,MACxB,OAAO,QAAQ,UAAU;AAAA,IAC3B;AAEA,QAAI;AACF,YAAM,KAAK,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eAAe,gBAAgB,KAAK;AAC1C,UAAI,aAAa,SAAS,WAAW,KAAK,aAAa,SAAS,UAAU,GAAG;AAC3E,cAAM,IAAI;AAAA,UACR,sBAAsB,QAAQ;AAAA,UAC9B;AAAA,UACA,EAAE,OAAO,MAAe;AAAA,QAC1B;AAAA,MACF;AACA,YAAM,IAAI;AAAA,QACR,gBAAgB,YAAY;AAAA,QAC5B,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KACJ,UACA,OACA,UAAuB,CAAC,GACT;AACf,SAAK,aAAa;AAElB,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA,YAAY,KAAK;AAAA,MACjB,SAAS,QAAQ,WAAW;AAAA,MAC5B,OAAO,QAAQ,SAAS;AAAA,IAC1B;AAEA,QAAI;AACF,YAAM,KAAK,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eAAe,gBAAgB,KAAK;AAC1C,UAAI,aAAa,SAAS,WAAW,KAAK,aAAa,SAAS,UAAU,GAAG;AAC3E,cAAM,IAAI;AAAA,UACR,sBAAsB,QAAQ;AAAA,UAC9B;AAAA,UACA,EAAE,OAAO,MAAe;AAAA,QAC1B;AAAA,MACF;AACA,YAAM,IAAI;AAAA,QACR,gBAAgB,YAAY;AAAA,QAC5B,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,UAAyB,CAAC,GAAkB;AACvD,SAAK,aAAa;AAElB,UAAM,cAAc;AAAA,MAClB,YAAY,KAAK;AAAA,MACjB,GAAG,QAAQ,KAAK;AAAA,MAChB,GAAG,QAAQ,KAAK;AAAA,MAChB,UAAU,QAAQ,YAAY;AAAA,IAChC;AAEA,QAAI;AACF,YAAM,KAAK,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,kBAAkB,gBAAgB,KAAK,CAAC;AAAA,QACxC,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,UAA6B,CAAC,GAAoB;AACjE,SAAK,aAAa;AAElB,UAAM,cAAc;AAAA,MAClB,YAAY,KAAK;AAAA,MACjB,WAAW,QAAQ,aAAa;AAAA,MAChC,QAAQ,QAAQ,UAAU;AAAA,MAC1B,SAAS,QAAQ,WAAW;AAAA,MAC5B,MAAM,QAAQ;AAAA,IAChB;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW;AAAA,QACrC;AAAA,QACA;AAAA,MACF;AAEA,UAAI,CAAC,SAAS,YAAY;AACxB,cAAM,IAAI,aAAa,8BAA8B;AAAA,MACvD;AAEA,aAAO,SAAS;AAAA,IAClB,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,sBAAsB,gBAAgB,KAAK,CAAC;AAAA,QAC5C,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBACJ,UACA,aAAuB,CAAC,MAAM,GAC9B,UAA0B,CAAC,GACE;AAC7B,SAAK,aAAa;AAElB,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA,YAAY,KAAK;AAAA,MACjB,aAAa,QAAQ,cAAc;AAAA,IACrC;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW;AAAA,QACrC;AAAA,QACA;AAAA,MACF;AAEA,aAAO,SAAS,YAAY,CAAC;AAAA,IAC/B,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,8BAA8B,gBAAgB,KAAK,CAAC;AAAA,QACpD,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2BA,MAAM,eACJ,UAAiC,CAAC,GACP;AAC3B,SAAK,aAAa;AAElB,UAAM,cAAc;AAAA,MAClB,YAAY,KAAK;AAAA,MACjB,qBAAqB,QAAQ,uBAAuB;AAAA,MACpD,iBAAiB,QAAQ,mBAAmB;AAAA,MAC5C,aAAa,QAAQ,cAAc;AAAA,IACrC;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW;AAAA,QACrC;AAAA,QACA;AAAA,MACF;AAEA,aAAO;AAAA,QACL,iBAAiB;AAAA,UACf,GAAI,SAAS,oBAAoB,CAAC;AAAA,UAClC,SAAS,SAAS,kBAAkB,WAAW;AAAA,QACjD;AAAA,QACA,qBAAqB,SAAS;AAAA,QAC9B,gBAAgB,SAAS;AAAA,MAC3B;AAAA,IACF,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,8BAA8B,gBAAgB,KAAK,CAAC;AAAA,QACpD,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAK,WAA0B,UAAU,KAAsB;AACnE,SAAK,aAAa;AAElB,QAAI,cAAmB;AAAA,MACrB,YAAY,KAAK;AAAA,MACjB;AAAA,IACF;AAEA,QAAI,UAAU,SAAS,WAAW;AAEhC,YAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,UAAU,EAAE,CAAC;AAC9D;AAAA,IACF;AAEA,kBAAc;AAAA,MACZ,GAAG;AAAA,MACH,WAAW,UAAU;AAAA,MACrB,UAAU,cAAc,YAAY,UAAU,WAAW;AAAA,IAC3D;AAEA,QAAI;AACF,YAAM,KAAK,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eAAe,gBAAgB,KAAK;AAC1C,UAAI,aAAa,SAAS,SAAS,GAAG;AACpC,cAAM,IAAI;AAAA,UACR,2BAA2B,UAAU,IAAI;AAAA,UACzC,EAAE,OAAO,MAAe;AAAA,QAC1B;AAAA,MACF;AACA,YAAM,IAAI;AAAA,QACR,gBAAgB,YAAY;AAAA,QAC5B,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAuB;AAC3B,QAAI,CAAC,KAAK,WAAW;AACnB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,KAAK,WAAW,OAAO,wBAAwB,KAAK,SAAS,EAAE;AAAA,IACvE,SAAS,OAAO;AAEd,cAAQ,KAAK,mCAAmC,KAAK,SAAS,KAAK,gBAAgB,KAAK,CAAC;AAAA,IAC3F,UAAE;AACA,WAAK,YAAY;AACjB,WAAK,KAAK,OAAO;AAAA,IACnB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,WAAoB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAqB;AAC3B,QAAI,CAAC,KAAK,WAAW;AACnB,YAAM,IAAI,aAAa,+BAA+B;AAAA,IACxD;AAAA,EACF;AACF;;;AChaO,IAAM,iBAAN,MAAqB;AAAA,EAK1B,YAAY,YAAwB,QAAiB,OAAO;AAH5D,SAAQ,iBAA8C,oBAAI,IAAI;AAI5D,SAAK,aAAa;AAClB,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cACJ,UAAiC,CAAC,GACT;AACzB,QAAI,KAAK,OAAO;AACd,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,cAAc;AAAA,MAClB,gBAAgB,QAAQ,iBAAiB;AAAA,MACzC,iBAAiB,QAAQ,kBAAkB;AAAA,MAC3C,YAAY,QAAQ;AAAA,IACtB;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW;AAAA,QACrC;AAAA,QACA;AAAA,MACF;AAEA,UAAI,CAAC,SAAS,YAAY;AACxB,cAAM,IAAI,oBAAoB,oCAAoC;AAAA,MACpE;AAEA,YAAM,UAAU,IAAI,eAAe,SAAS,YAAY,KAAK,UAAU;AACvE,WAAK,eAAe,IAAI,SAAS,YAAY,OAAO;AAGpD,cAAQ,GAAG,SAAS,MAAM;AACxB,aAAK,eAAe,OAAO,SAAS,UAAU;AAAA,MAChD,CAAC;AAED,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAM,IAAI;AAAA,QACR,qCAAqC,YAAY;AAAA,QACjD,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,WAAgD;AAC/D,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW;AAAA,QACrC,wBAAwB,SAAS;AAAA,MACnC;AAEA,aAAO;AAAA,QACL,WAAW,SAAS;AAAA,QACpB,QAAQ,SAAS,UAAU;AAAA,QAC3B,WAAW,SAAS;AAAA,QACpB,eAAe,SAAS;AAAA,QACxB,gBAAgB,SAAS;AAAA,QACzB,WAAW,SAAS;AAAA,MACtB;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAM,IAAI;AAAA,QACR,+BAA+B,YAAY;AAAA,QAC3C,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAA8C;AAClD,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW,IAAS,uBAAuB;AAEvE,UAAI,CAAC,MAAM,QAAQ,SAAS,QAAQ,GAAG;AACrC,eAAO,CAAC;AAAA,MACV;AAEA,aAAO,SAAS,SAAS,IAAI,CAAC,aAAkB;AAAA,QAC9C,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ,UAAU;AAAA,QAC1B,WAAW,QAAQ;AAAA,QACnB,eAAe,QAAQ;AAAA,QACvB,gBAAgB,QAAQ;AAAA,QACxB,WAAW,QAAQ;AAAA,MACrB,EAAE;AAAA,IACJ,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAM,IAAI;AAAA,QACR,4BAA4B,YAAY;AAAA,QACxC,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,WAA+C;AAC7D,WAAO,KAAK,eAAe,IAAI,SAAS;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAqC;AACnC,WAAO,MAAM,KAAK,KAAK,eAAe,OAAO,CAAC;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAAkC;AACtC,UAAM,WAAW,MAAM,KAAK,KAAK,eAAe,OAAO,CAAC;AAExD,UAAM,QAAQ;AAAA,MACZ,SAAS,IAAI,aAAW,QAAQ,MAAM,CAAC;AAAA,IACzC;AAEA,SAAK,eAAe,MAAM;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SACJ,KACA,UAA2B,CAAC,GACD;AAC3B,QAAI,CAAC,KAAK,OAAO;AACf,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,cAAc;AAAA,MAClB;AAAA,MACA,cAAc,QAAQ,eAAe;AAAA,IACvC;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW;AAAA,QACrC;AAAA,QACA;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS,SAAS,YAAY;AAAA,QAC9B,KAAK,SAAS,OAAO;AAAA,QACrB,OAAO,SAAS;AAAA,QAChB,QAAQ,SAAS;AAAA,MACnB;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAM,IAAI;AAAA,QACR,sBAAsB,YAAY;AAAA,QAClC,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eACJ,UAAiC,CAAC,GACP;AAC3B,QAAI,CAAC,KAAK,OAAO;AACf,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ,KAAK;AAChB,YAAM,IAAI,wBAAwB,+BAA+B;AAAA,IACnE;AAEA,UAAM,cAAc;AAAA,MAClB,KAAK,QAAQ;AAAA,MACb,qBAAqB,QAAQ,uBAAuB;AAAA,MACpD,iBAAiB,QAAQ,mBAAmB;AAAA,MAC5C,aAAa,QAAQ,cAAc;AAAA,IACrC;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW;AAAA,QACrC;AAAA,QACA;AAAA,MACF;AAEA,aAAO;AAAA,QACL,iBAAiB;AAAA,UACf,GAAI,SAAS,oBAAoB,CAAC;AAAA,UAClC,SAAS,SAAS,kBAAkB,WAAW;AAAA,QACjD;AAAA,QACA,qBAAqB,SAAS;AAAA,QAC9B,gBAAgB,SAAS;AAAA,MAC3B;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAM,IAAI;AAAA,QACR,8BAA8B,YAAY;AAAA,QAC1C,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAyB;AAC7B,UAAM,KAAK,iBAAiB;AAAA,EAC9B;AACF;;;ACjPA,uBAAqB;AA0Bd,IAAM,UAAN,MAAc;AAAA,EAMnB,YAAY,QAAgB,UAA0B,CAAC,GAAG;AAJ1D,SAAQ,aAA4B;AAKlC,SAAK,QAAQ,QAAQ,SAAS;AAG9B,QAAI,CAAC,KAAK,SAAS,CAAC,QAAQ;AAC1B,YAAM,IAAI,oBAAoB,oCAAoC;AAAA,IACpE;AAEA,UAAM,SAAS;AAAA,MACb,SAAS,KAAK,QACT,QAAQ,YAAY,iCACpB,QAAQ,WAAW;AAAA,MACxB,SAAS,QAAQ,WAAW;AAAA;AAAA,MAC5B,YAAY,QAAQ,cAAc;AAAA,MAClC,YAAY,QAAQ,cAAc;AAAA,MAClC,QAAQ,UAAU;AAAA,IACpB;AAEA,SAAK,aAAa,IAAI,WAAW,MAAM;AACvC,SAAK,UAAU,IAAI,eAAe,KAAK,YAAY,KAAK,KAAK;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,eAA6B;AAClD,QAAI,KAAK,OAAO;AACd,YAAM,IAAI;AAAA,QACR,GAAG,aAAa;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QACJ,SACA,UAA0B,CAAC,GACD;AAE1B,QAAI,YAAY,QAAQ,aAAa,KAAK;AAC1C,QAAI,CAAC,KAAK,SAAS,CAAC,WAAW;AAC7B,kBAAY,MAAM,KAAK,cAAc;AAAA,IACvC;AAEA,UAAM,cAAmB;AAAA,MACvB;AAAA,MACA,UAAU,QAAQ,YAAY;AAAA,MAC9B,SAAS,QAAQ,WAAW;AAAA,IAC9B;AAGA,QAAI,CAAC,KAAK,SAAS,WAAW;AAC5B,kBAAY,aAAa;AAAA,IAC3B;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW;AAAA,QACrC;AAAA,QACA;AAAA,MACF;AAGA,UAAI,SAAS,YAAY;AACvB,aAAK,aAAa,SAAS;AAAA,MAC7B;AAEA,aAAO;AAAA,QACL,QAAQ,SAAS,UAAU,SAAS,UAAU;AAAA,QAC9C,SAAS,SAAS,YAAY;AAAA,QAC9B,eAAe,SAAS,kBAAkB;AAAA,QAC1C,WAAW,SAAS;AAAA,QACpB,OAAO,SAAS;AAAA,MAClB;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAM,IAAI;AAAA,QACR,0BAA0B,YAAY;AAAA,QACtC;AAAA,QACA;AAAA,QACA,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aACJ,SACA,UAA0B,CAAC,GACI;AAC/B,SAAK,eAAe,iBAAiB;AAGrC,QAAI,YAAY,QAAQ,aAAa,KAAK;AAC1C,QAAI,CAAC,WAAW;AACd,kBAAY,MAAM,KAAK,cAAc;AAAA,IACvC;AAEA,UAAM,cAAc;AAAA,MAClB;AAAA,MACA,UAAU,QAAQ,YAAY;AAAA,MAC9B,SAAS,QAAQ,WAAW;AAAA,MAC5B,YAAY;AAAA,IACd;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW;AAAA,QACrC;AAAA,QACA;AAAA,MACF;AAGA,UAAI,SAAS,YAAY;AACvB,aAAK,aAAa,SAAS;AAAA,MAC7B;AAEA,aAAO;AAAA,QACL,QAAQ,SAAS;AAAA,QACjB,QAAQ,SAAS,UAAU;AAAA,QAC3B,QAAQ,SAAS,UAAU,SAAS;AAAA,QACpC,SAAS,SAAS;AAAA,QAClB,eAAe,SAAS;AAAA,QACxB,WAAW,SAAS;AAAA,QACpB,OAAO,SAAS;AAAA,MAClB;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAM,IAAI;AAAA,QACR,gCAAgC,YAAY;AAAA,QAC5C;AAAA,QACA;AAAA,QACA,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OACJ,OACA,UAAyB,CAAC,GACH;AACvB,SAAK,eAAe,aAAa;AACjC,UAAM,WAAW,IAAI,iBAAAC,QAAS;AAG9B,eAAW,QAAQ,OAAO;AACxB,UAAI,OAAO,SAAS,KAAK,OAAO,GAAG;AACjC,iBAAS,OAAO,SAAS,KAAK,SAAS,KAAK,IAAI;AAAA,MAClD,OAAO;AACL,iBAAS,OAAO,SAAS,OAAO,KAAK,KAAK,OAAO,GAAG,KAAK,IAAI;AAAA,MAC/D;AAEA,UAAI,KAAK,MAAM;AACb,iBAAS,OAAO,SAAS,KAAK,IAAI;AAAA,MACpC;AAAA,IACF;AAGA,QAAI,QAAQ,aAAa,KAAK,YAAY;AACxC,eAAS,OAAO,cAAc,QAAQ,aAAa,KAAK,UAAW;AAAA,IACrE;AACA,QAAI,QAAQ,YAAY;AACtB,eAAS,OAAO,eAAe,QAAQ,UAAU;AAAA,IACnD;AACA,QAAI,QAAQ,cAAc,QAAW;AACnC,eAAS,OAAO,aAAa,OAAO,QAAQ,SAAS,CAAC;AAAA,IACxD;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW;AAAA,QACrC;AAAA,QACA;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS,SAAS,YAAY;AAAA,QAC9B,OAAO,SAAS,SAAS,CAAC;AAAA,QAC1B,SAAS,SAAS;AAAA,MACpB;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAM,IAAI;AAAA,QACR,uBAAuB,YAAY;AAAA,QACnC,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAiC;AACrC,SAAK,eAAe,oBAAoB;AAExC,QAAI;AAEF,YAAM,WAAW,MAAM,KAAK,WAAW,KAAU,wBAAwB;AAAA,QACvE,SAAS,KAAK,WAAW;AAAA,MAC3B,CAAC;AAED,UAAI,SAAS,YAAY;AACvB,aAAK,aAAa,SAAS;AAC3B,eAAO,SAAS;AAAA,MAClB;AAEA,YAAM,IAAI,aAAa,iDAAiD;AAAA,IAC1E,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAM,IAAI;AAAA,QACR,4BAA4B,YAAY;AAAA,QACxC,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,WAAmC;AACpD,UAAM,kBAAkB,aAAa,KAAK;AAE1C,QAAI,CAAC,iBAAiB;AACpB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,KAAK,WAAW,OAAO,gBAAgB,eAAe,EAAE;AAE9D,UAAI,oBAAoB,KAAK,YAAY;AACvC,aAAK,aAAa;AAAA,MACpB;AAAA,IACF,SAAS,OAAO;AAEd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,cAAQ,KAAK,2BAA2B,eAAe,KAAK,YAAY;AAAA,IAC1E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,WAAyC;AACtD,SAAK,eAAe,gBAAgB;AAEpC,UAAM,kBAAkB,aAAa,KAAK;AAE1C,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAI,aAAa,oCAAoC;AAAA,IAC7D;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW;AAAA,QACrC,sBAAsB,eAAe;AAAA,MACvC;AAEA,aAAO;AAAA,QACL,cAAc,SAAS,iBAAiB;AAAA,QACxC,eAAe,SAAS,kBAAkB;AAAA,QAC1C,gBAAgB,SAAS,mBAAmB;AAAA,QAC5C,YAAY,SAAS,eAAe;AAAA,MACtC;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAM,IAAI;AAAA,QACR,8BAA8B,YAAY;AAAA,QAC1C,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SACJ,UACA,UAA2B,CAAC,GACH;AACzB,SAAK,eAAe,eAAe;AAEnC,UAAM,kBAAkB,QAAQ,aAAa,KAAK;AAElD,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAI,aAAa,oCAAoC;AAAA,IAC7D;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW,QAAQ,aAAa;AAAA,QAC1D;AAAA,QACA,YAAY;AAAA,MACd,CAAC;AAED,YAAM,UAAU,OAAO,KAAK,QAAQ;AAEpC,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA,MAAM,QAAQ;AAAA,MAChB;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAM,IAAI;AAAA,QACR,yBAAyB,YAAY;AAAA,QACrC,EAAE,OAAO,MAAe;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,YAA2B;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAyB;AAC7B,QAAI,KAAK,YAAY;AACnB,YAAM,KAAK,aAAa;AAAA,IAC1B;AACA,UAAM,KAAK,QAAQ,QAAQ;AAAA,EAC7B;AACF;","names":["axios","FormData"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/client/HTTPClient.ts","../src/errors/BaseError.ts","../src/utils/retry.ts","../src/client/BrowserSession.ts","../src/client/BrowserManager.ts","../src/client/InstaVM.ts"],"sourcesContent":["// Main client\nexport { InstaVM } from './client/InstaVM';\nexport type { InstaVMOptions } from './client/InstaVM';\n\n// Browser automation\nexport { BrowserManager } from './client/BrowserManager';\nexport { BrowserSession } from './client/BrowserSession';\n\n// Types\nexport type {\n ExecuteOptions,\n ExecutionResult,\n AsyncExecutionResult,\n FileUpload,\n UploadOptions,\n UploadResult,\n UsageStats,\n DownloadOptions,\n DownloadResult,\n} from './types/execution';\n\nexport type {\n BrowserSessionOptions,\n BrowserSessionInfo,\n NavigateOptions,\n NavigationResult,\n ClickOptions,\n TypeOptions,\n FillOptions,\n ScrollOptions,\n ScreenshotOptions,\n WaitCondition,\n ExtractedElement,\n ExtractOptions,\n ExtractContentOptions,\n ExtractedContent,\n InteractiveElement,\n ContentAnchor,\n} from './types/browser';\n\nexport type {\n ApiResponse,\n HttpClientConfig,\n RequestConfig,\n RetryConfig,\n} from './types/api';\n\n// Errors\nexport {\n InstaVMError,\n AuthenticationError,\n RateLimitError,\n QuotaExceededError,\n NetworkError,\n ExecutionError,\n SessionError,\n BrowserError,\n BrowserSessionError,\n BrowserInteractionError,\n BrowserTimeoutError,\n BrowserNavigationError,\n ElementNotFoundError,\n UnsupportedOperationError,\n} from './errors/BaseError';","import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';\nimport FormData from 'form-data';\nimport {\n InstaVMError,\n AuthenticationError,\n RateLimitError,\n QuotaExceededError,\n NetworkError,\n} from '../errors/BaseError';\nimport { withRetry } from '../utils/retry';\nimport type { HttpClientConfig, RequestConfig } from '../types/api';\n\n/**\n * HTTP client with authentication, retry logic, and error handling\n */\nexport class HTTPClient {\n private client: AxiosInstance;\n private config: HttpClientConfig;\n\n get apiKey(): string {\n return this.config.apiKey;\n }\n\n constructor(config: HttpClientConfig) {\n this.config = config;\n \n this.client = axios.create({\n baseURL: config.baseURL,\n timeout: config.timeout,\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'instavm-js-sdk/0.1.0',\n },\n });\n\n this.setupInterceptors();\n }\n\n private setupInterceptors(): void {\n // Request interceptor - add authentication\n this.client.interceptors.request.use(\n (config) => {\n // Add API key to headers for browser endpoints\n if (config.url?.includes('/browser/')) {\n config.headers['X-API-Key'] = this.config.apiKey;\n }\n \n return config;\n },\n (error) => Promise.reject(error)\n );\n\n // Response interceptor - handle errors\n this.client.interceptors.response.use(\n (response) => response,\n (error) => {\n const axiosError = error;\n const status = axiosError.response?.status;\n const data = axiosError.response?.data;\n const message = data?.message || data?.error || axiosError.message;\n\n switch (status) {\n case 401:\n throw new AuthenticationError(message, {\n statusCode: status,\n response: data,\n });\n case 402:\n throw new QuotaExceededError(message, {\n statusCode: status,\n response: data,\n });\n case 429:\n const retryAfter = parseInt(\n axiosError.response?.headers['retry-after'] || '60'\n );\n throw new RateLimitError(message, retryAfter, {\n statusCode: status,\n response: data,\n });\n case 500:\n case 502:\n case 503:\n case 504:\n throw new NetworkError(message, {\n statusCode: status,\n response: data,\n });\n default:\n if (axiosError.code === 'ECONNABORTED') {\n throw new NetworkError('Request timeout', {\n code: axiosError.code,\n });\n }\n throw new InstaVMError(message, {\n statusCode: status,\n response: data,\n code: axiosError.code,\n });\n }\n }\n );\n }\n\n /**\n * Make an HTTP request with retry logic\n */\n async request<T = any>(requestConfig: RequestConfig): Promise<T> {\n const axiosConfig: AxiosRequestConfig = {\n method: requestConfig.method,\n url: requestConfig.url,\n headers: requestConfig.headers,\n data: requestConfig.data,\n params: requestConfig.params,\n timeout: requestConfig.timeout || this.config.timeout,\n };\n\n const makeRequest = async (): Promise<T> => {\n const response: AxiosResponse<T> = await this.client.request(axiosConfig);\n return response.data;\n };\n\n return withRetry(makeRequest, {\n retries: this.config.maxRetries,\n retryDelay: this.config.retryDelay,\n });\n }\n\n /**\n * POST request with JSON body\n */\n async post<T = any>(\n url: string,\n data?: any,\n headers?: Record<string, string>,\n timeout?: number\n ): Promise<T> {\n return this.request<T>({\n method: 'POST',\n url,\n data,\n headers,\n timeout,\n });\n }\n\n /**\n * POST request for code execution (uses X-API-Key header like Python client)\n */\n async postExecution<T = any>(\n url: string,\n data: any,\n headers?: Record<string, string>,\n timeout?: number\n ): Promise<T> {\n const requestHeaders = {\n 'X-API-Key': this.config.apiKey,\n ...headers,\n };\n\n return this.request<T>({\n method: 'POST',\n url,\n data,\n headers: requestHeaders,\n timeout,\n });\n }\n\n /**\n * POST request with form data (for file uploads)\n */\n async postFormData<T = any>(\n url: string,\n formData: FormData,\n headers?: Record<string, string>\n ): Promise<T> {\n const requestHeaders = {\n ...formData.getHeaders(),\n ...headers,\n };\n\n return this.request<T>({\n method: 'POST',\n url,\n data: formData,\n headers: requestHeaders,\n });\n }\n\n /**\n * GET request\n */\n async get<T = any>(\n url: string,\n params?: Record<string, any>,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>({\n method: 'GET',\n url,\n params,\n headers,\n });\n }\n\n /**\n * DELETE request\n */\n async delete<T = any>(\n url: string,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>({\n method: 'DELETE',\n url,\n headers,\n });\n }\n\n /**\n * POST request that returns raw binary data (for file downloads)\n */\n async postRaw(\n url: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<ArrayBuffer> {\n const requestHeaders = {\n 'X-API-Key': this.config.apiKey,\n ...headers,\n };\n\n const axiosConfig: AxiosRequestConfig = {\n method: 'POST',\n url,\n data,\n headers: requestHeaders,\n responseType: 'arraybuffer',\n timeout: this.config.timeout,\n };\n\n const makeRequest = async (): Promise<ArrayBuffer> => {\n const response: AxiosResponse<ArrayBuffer> = await this.client.request(axiosConfig);\n return response.data;\n };\n\n return withRetry(makeRequest, {\n retries: this.config.maxRetries,\n retryDelay: this.config.retryDelay,\n });\n }\n}","/**\n * Base error class for all InstaVM SDK errors\n */\nexport class InstaVMError extends Error {\n public readonly name: string;\n public readonly code?: string;\n public readonly statusCode?: number;\n public readonly response?: any;\n\n constructor(\n message: string,\n options?: {\n code?: string;\n statusCode?: number;\n response?: any;\n cause?: Error;\n }\n ) {\n super(message);\n this.name = this.constructor.name;\n this.code = options?.code;\n this.statusCode = options?.statusCode;\n this.response = options?.response;\n\n // Ensure proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n\n // Capture stack trace, excluding constructor call from it\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Authentication-related errors (401, invalid API key, etc.)\n */\nexport class AuthenticationError extends InstaVMError {\n constructor(message: string = 'Authentication failed', options?: any) {\n super(message, { ...options, statusCode: 401 });\n }\n}\n\n/**\n * Rate limiting errors (429)\n */\nexport class RateLimitError extends InstaVMError {\n public readonly retryAfter?: number;\n\n constructor(\n message: string = 'Rate limit exceeded',\n retryAfter?: number,\n options?: any\n ) {\n super(message, { ...options, statusCode: 429 });\n this.retryAfter = retryAfter;\n }\n}\n\n/**\n * Quota/usage limit exceeded errors\n */\nexport class QuotaExceededError extends InstaVMError {\n constructor(message: string = 'Usage quota exceeded', options?: any) {\n super(message, { ...options, statusCode: 402 });\n }\n}\n\n/**\n * Network-related errors (timeouts, connection issues, 5xx errors)\n */\nexport class NetworkError extends InstaVMError {\n constructor(message: string = 'Network error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Code execution errors\n */\nexport class ExecutionError extends InstaVMError {\n public readonly executionOutput?: string;\n public readonly executionTime?: number;\n\n constructor(\n message: string,\n executionOutput?: string,\n executionTime?: number,\n options?: any\n ) {\n super(message, options);\n this.executionOutput = executionOutput;\n this.executionTime = executionTime;\n }\n}\n\n/**\n * Session management errors\n */\nexport class SessionError extends InstaVMError {\n constructor(message: string = 'Session error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser automation base error\n */\nexport class BrowserError extends InstaVMError {\n constructor(message: string = 'Browser error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser session management errors\n */\nexport class BrowserSessionError extends BrowserError {\n constructor(message: string = 'Browser session error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser interaction errors (click, type, etc.)\n */\nexport class BrowserInteractionError extends BrowserError {\n constructor(message: string = 'Browser interaction error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser timeout errors\n */\nexport class BrowserTimeoutError extends BrowserError {\n constructor(message: string = 'Browser operation timed out', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser navigation errors\n */\nexport class BrowserNavigationError extends BrowserError {\n constructor(message: string = 'Browser navigation error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Element not found errors\n */\nexport class ElementNotFoundError extends BrowserError {\n public readonly selector?: string;\n\n constructor(\n message: string = 'Element not found',\n selector?: string,\n options?: any\n ) {\n super(message, options);\n this.selector = selector;\n }\n}\n\n/**\n * Unsupported operation error (e.g., operations not available in local mode)\n */\nexport class UnsupportedOperationError extends InstaVMError {\n constructor(message: string = 'Operation not supported', options?: any) {\n super(message, options);\n }\n}","import { NetworkError, RateLimitError } from '../errors/BaseError';\n\nexport interface RetryOptions {\n retries: number;\n retryDelay: number;\n maxRetryDelay?: number;\n retryCondition?: (error: any) => boolean;\n}\n\n/**\n * Default retry condition - retry on network errors and 5xx server errors\n */\nexport function defaultRetryCondition(error: any): boolean {\n if (error instanceof NetworkError) return true;\n if (error instanceof RateLimitError) return true;\n \n // Axios error with status code\n if (error.response?.status >= 500) return true;\n \n // Network/timeout errors\n if (error.code === 'ECONNABORTED' || error.code === 'ETIMEDOUT') return true;\n if (error.code === 'ECONNRESET' || error.code === 'ENOTFOUND') return true;\n \n return false;\n}\n\n/**\n * Calculate exponential backoff delay\n */\nexport function calculateRetryDelay(\n attempt: number,\n baseDelay: number,\n maxDelay = 30000\n): number {\n const exponentialDelay = baseDelay * Math.pow(2, attempt - 1);\n const jitteredDelay = exponentialDelay * (0.5 + Math.random() * 0.5);\n return Math.min(jitteredDelay, maxDelay);\n}\n\n/**\n * Retry a function with exponential backoff\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions\n): Promise<T> {\n const {\n retries,\n retryDelay,\n maxRetryDelay = 30000,\n retryCondition = defaultRetryCondition,\n } = options;\n\n let lastError: any;\n\n for (let attempt = 1; attempt <= retries + 1; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n\n // Don't retry on last attempt\n if (attempt === retries + 1) {\n break;\n }\n\n // Check if we should retry this error\n if (!retryCondition(error)) {\n break;\n }\n\n // Calculate delay for this attempt\n const delay = calculateRetryDelay(attempt, retryDelay, maxRetryDelay);\n \n // Wait before retrying\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n\n throw lastError;\n}","import { EventEmitter } from 'eventemitter3';\nimport type { HTTPClient } from './HTTPClient';\nimport {\n BrowserError,\n BrowserInteractionError,\n BrowserNavigationError,\n BrowserTimeoutError,\n ElementNotFoundError,\n} from '../errors/BaseError';\nimport type {\n NavigateOptions,\n NavigationResult,\n ClickOptions,\n TypeOptions,\n FillOptions,\n ScrollOptions,\n ScreenshotOptions,\n WaitCondition,\n ExtractedElement,\n ExtractOptions,\n ExtractContentOptions,\n ExtractedContent,\n} from '../types/browser';\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * Browser session for automation\n */\nexport class BrowserSession extends EventEmitter {\n public readonly sessionId: string;\n private httpClient: HTTPClient;\n private _isActive: boolean = true;\n\n constructor(sessionId: string, httpClient: HTTPClient) {\n super();\n this.sessionId = sessionId;\n this.httpClient = httpClient;\n }\n\n /**\n * Navigate to a URL\n */\n async navigate(\n url: string,\n options: NavigateOptions = {}\n ): Promise<NavigationResult> {\n this.ensureActive();\n\n const requestData = {\n url,\n session_id: this.sessionId,\n wait_timeout: options.waitTimeout || 30000,\n wait_until: options.waitUntil || 'load',\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/navigate',\n requestData\n );\n\n const result: NavigationResult = {\n success: response.success !== false,\n url: response.url || url,\n title: response.title,\n status: response.status,\n };\n\n this.emit('navigation', result);\n return result;\n } catch (error) {\n const navigationError = new BrowserNavigationError(\n `Navigation failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n this.emit('error', navigationError);\n throw navigationError;\n }\n }\n\n /**\n * Click an element\n */\n async click(selector: string, options: ClickOptions = {}): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n selector,\n session_id: this.sessionId,\n timeout: options.timeout || 10000,\n button: options.button || 'left',\n click_count: options.clickCount || 1,\n force: options.force || false,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/click',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('not found') || errorMessage.includes('selector')) {\n throw new ElementNotFoundError(\n `Element not found: ${selector}`,\n selector,\n { cause: error as Error }\n );\n }\n if (errorMessage.includes('timeout')) {\n throw new BrowserTimeoutError(\n `Click timeout: ${selector}`,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Click failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Type text into an element\n */\n async type(\n selector: string,\n text: string,\n options: TypeOptions = {}\n ): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n selector,\n text,\n session_id: this.sessionId,\n timeout: options.timeout || 10000,\n delay: options.delay || 0,\n clear: options.clear !== false,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/type',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('not found') || errorMessage.includes('selector')) {\n throw new ElementNotFoundError(\n `Element not found: ${selector}`,\n selector,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Type failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Fill a form field\n */\n async fill(\n selector: string,\n value: string,\n options: FillOptions = {}\n ): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n selector,\n value,\n session_id: this.sessionId,\n timeout: options.timeout || 10000,\n force: options.force || false,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/fill',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('not found') || errorMessage.includes('selector')) {\n throw new ElementNotFoundError(\n `Element not found: ${selector}`,\n selector,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Fill failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Scroll the page\n */\n async scroll(options: ScrollOptions = {}): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n session_id: this.sessionId,\n x: options.x || 0,\n y: options.y || 500,\n behavior: options.behavior || 'auto',\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/scroll',\n requestData\n );\n } catch (error) {\n throw new BrowserInteractionError(\n `Scroll failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Take a screenshot\n */\n async screenshot(options: ScreenshotOptions = {}): Promise<string> {\n this.ensureActive();\n\n const requestData = {\n session_id: this.sessionId,\n full_page: options.fullPage !== false,\n format: options.format || 'png',\n quality: options.quality || 90,\n clip: options.clip,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/screenshot',\n requestData\n );\n\n if (!response.screenshot) {\n throw new BrowserError('Screenshot data not returned');\n }\n\n return response.screenshot;\n } catch (error) {\n throw new BrowserInteractionError(\n `Screenshot failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Extract elements from the page\n */\n async extractElements(\n selector: string,\n attributes: string[] = ['text'],\n options: ExtractOptions = {}\n ): Promise<ExtractedElement[]> {\n this.ensureActive();\n\n const requestData = {\n selector,\n attributes,\n session_id: this.sessionId,\n max_results: options.maxResults || 100,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/extract',\n requestData\n );\n\n return response.elements || [];\n } catch (error) {\n throw new BrowserInteractionError(\n `Element extraction failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Extract LLM-friendly content from the current page\n *\n * Returns clean article content, interactive elements, and content anchors\n * for intelligent browser automation with LLMs.\n *\n * @param options - Content extraction options\n * @returns Extracted content with readable text, interactive elements, and content anchors\n *\n * @example\n * ```typescript\n * const content = await session.extractContent();\n *\n * // LLM reads clean content\n * const article = content.readableContent.content;\n *\n * // LLM finds \"Sign Up\" in content and uses anchors to get selector\n * const signUpAnchor = content.contentAnchors?.find(\n * anchor => anchor.text.toLowerCase().includes('sign up')\n * );\n * if (signUpAnchor) {\n * await session.click(signUpAnchor.selector);\n * }\n * ```\n */\n async extractContent(\n options: ExtractContentOptions = {}\n ): Promise<ExtractedContent> {\n this.ensureActive();\n\n const requestData = {\n session_id: this.sessionId,\n include_interactive: options.includeInteractive !== false,\n include_anchors: options.includeAnchors !== false,\n max_anchors: options.maxAnchors ?? 50,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/content',\n requestData\n );\n\n return {\n readableContent: {\n ...(response.readable_content || {}),\n content: response.readable_content?.content || '',\n },\n interactiveElements: response.interactive_elements,\n contentAnchors: response.content_anchors,\n };\n } catch (error) {\n throw new BrowserInteractionError(\n `Content extraction failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Wait for a condition\n */\n async wait(condition: WaitCondition, timeout = 10000): Promise<void> {\n this.ensureActive();\n\n let requestData: any = {\n session_id: this.sessionId,\n timeout,\n };\n\n if (condition.type === 'timeout') {\n // Simple timeout wait\n await new Promise(resolve => setTimeout(resolve, condition.ms));\n return;\n }\n\n requestData = {\n ...requestData,\n condition: condition.type,\n selector: 'selector' in condition ? condition.selector : undefined,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/wait',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('timeout')) {\n throw new BrowserTimeoutError(\n `Wait condition timeout: ${condition.type}`,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Wait failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Close the browser session\n */\n async close(): Promise<void> {\n if (!this._isActive) {\n return;\n }\n\n try {\n await this.httpClient.delete(`/v1/browser/sessions/${this.sessionId}`);\n } catch (error) {\n // Don't throw on close errors - session might already be closed\n console.warn(`Failed to close browser session ${this.sessionId}:`, getErrorMessage(error));\n } finally {\n this._isActive = false;\n this.emit('close');\n }\n }\n\n /**\n * Check if session is active\n */\n get isActive(): boolean {\n return this._isActive;\n }\n\n /**\n * Ensure session is active before operations\n */\n private ensureActive(): void {\n if (!this._isActive) {\n throw new BrowserError('Browser session is not active');\n }\n }\n}","import type { HTTPClient } from './HTTPClient';\nimport { BrowserSession } from './BrowserSession';\nimport { BrowserSessionError, BrowserNavigationError, BrowserInteractionError, UnsupportedOperationError } from '../errors/BaseError';\nimport type {\n BrowserSessionOptions,\n BrowserSessionInfo,\n NavigateOptions,\n NavigationResult,\n ExtractContentOptions,\n ExtractedContent,\n} from '../types/browser';\n\n/**\n * Browser automation manager\n */\nexport class BrowserManager {\n private httpClient: HTTPClient;\n private activeSessions: Map<string, BrowserSession> = new Map();\n private local: boolean;\n\n constructor(httpClient: HTTPClient, local: boolean = false) {\n this.httpClient = httpClient;\n this.local = local;\n }\n\n /**\n * Create a new browser session\n */\n async createSession(\n options: BrowserSessionOptions = {}\n ): Promise<BrowserSession> {\n if (this.local) {\n throw new UnsupportedOperationError(\n 'Browser session management is not supported in local mode. Use navigate() or extractContent() with URL directly.'\n );\n }\n\n const requestData = {\n viewport_width: options.viewportWidth || 1920,\n viewport_height: options.viewportHeight || 1080,\n user_agent: options.userAgent,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/sessions/',\n requestData\n );\n\n if (!response.session_id) {\n throw new BrowserSessionError('No session ID returned from server');\n }\n\n const session = new BrowserSession(response.session_id, this.httpClient);\n this.activeSessions.set(response.session_id, session);\n\n // Clean up session from our tracking when it's closed\n session.on('close', () => {\n this.activeSessions.delete(response.session_id);\n });\n\n return session;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserSessionError(\n `Failed to create browser session: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Get information about a specific session\n */\n async getSession(sessionId: string): Promise<BrowserSessionInfo> {\n try {\n const response = await this.httpClient.get<any>(\n `/v1/browser/sessions/${sessionId}`\n );\n\n return {\n sessionId: response.session_id,\n status: response.status || 'active',\n createdAt: response.created_at,\n viewportWidth: response.viewport_width,\n viewportHeight: response.viewport_height,\n userAgent: response.user_agent,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserSessionError(\n `Failed to get session info: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * List all browser sessions\n */\n async listSessions(): Promise<BrowserSessionInfo[]> {\n try {\n const response = await this.httpClient.get<any>('/v1/browser/sessions/');\n\n if (!Array.isArray(response.sessions)) {\n return [];\n }\n\n return response.sessions.map((session: any) => ({\n sessionId: session.session_id,\n status: session.status || 'active',\n createdAt: session.created_at,\n viewportWidth: session.viewport_width,\n viewportHeight: session.viewport_height,\n userAgent: session.user_agent,\n }));\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserSessionError(\n `Failed to list sessions: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Get a locally tracked session\n */\n getLocalSession(sessionId: string): BrowserSession | undefined {\n return this.activeSessions.get(sessionId);\n }\n\n /**\n * Get all locally tracked sessions\n */\n getLocalSessions(): BrowserSession[] {\n return Array.from(this.activeSessions.values());\n }\n\n /**\n * Close all active sessions\n */\n async closeAllSessions(): Promise<void> {\n const sessions = Array.from(this.activeSessions.values());\n \n await Promise.allSettled(\n sessions.map(session => session.close())\n );\n \n this.activeSessions.clear();\n }\n\n /**\n * Navigate to a URL (local mode support - no session required)\n */\n async navigate(\n url: string,\n options: NavigateOptions = {}\n ): Promise<NavigationResult> {\n if (!this.local) {\n throw new UnsupportedOperationError(\n 'navigate() without session is only supported in local mode. In cloud mode, create a session first.'\n );\n }\n\n const requestData = {\n url,\n wait_timeout: options.waitTimeout || 30000,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/navigate',\n requestData\n );\n\n return {\n success: response.success !== false,\n url: response.url || url,\n title: response.title,\n status: response.status,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserNavigationError(\n `Navigation failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Extract LLM-friendly content (local mode support - no session required)\n */\n async extractContent(\n options: ExtractContentOptions = {}\n ): Promise<ExtractedContent> {\n if (!this.local) {\n throw new UnsupportedOperationError(\n 'extractContent() without session is only supported in local mode. In cloud mode, create a session first.'\n );\n }\n\n if (!options.url) {\n throw new BrowserInteractionError('url is required in local mode');\n }\n\n const requestData = {\n url: options.url,\n include_interactive: options.includeInteractive !== false,\n include_anchors: options.includeAnchors !== false,\n max_anchors: options.maxAnchors ?? 50,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/content',\n requestData\n );\n\n return {\n readableContent: {\n ...(response.readable_content || {}),\n content: response.readable_content?.content || '',\n },\n interactiveElements: response.interactive_elements,\n contentAnchors: response.content_anchors,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserInteractionError(\n `Content extraction failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Clean up resources\n */\n async dispose(): Promise<void> {\n await this.closeAllSessions();\n }\n}","import { HTTPClient } from './HTTPClient';\nimport { BrowserManager } from './BrowserManager';\nimport FormData from 'form-data';\nimport { SessionError, ExecutionError, UnsupportedOperationError, AuthenticationError } from '../errors/BaseError';\nimport type {\n ExecuteOptions,\n ExecutionResult,\n AsyncExecutionResult,\n FileUpload,\n UploadOptions,\n UploadResult,\n UsageStats,\n DownloadOptions,\n DownloadResult,\n} from '../types/execution';\n\nexport interface InstaVMOptions {\n baseURL?: string;\n /**\n * Timeout in milliseconds. Used for HTTP request timeout and sent to API as VM lifetime (in seconds).\n * Default: 300000 (5 minutes)\n */\n timeout?: number;\n maxRetries?: number;\n retryDelay?: number;\n local?: boolean;\n localURL?: string;\n}\n\n/**\n * Main InstaVM client class\n */\nexport class InstaVM {\n private httpClient: HTTPClient;\n private _sessionId: string | null = null;\n public readonly browser: BrowserManager;\n public readonly local: boolean;\n private readonly timeout: number;\n\n constructor(apiKey: string, options: InstaVMOptions = {}) {\n this.local = options.local || false;\n this.timeout = options.timeout || 300000; // 300000 milliseconds (5 minutes)\n\n // In local mode, API key is optional\n if (!this.local && !apiKey) {\n throw new AuthenticationError('API key is required for cloud mode');\n }\n\n const config = {\n baseURL: this.local\n ? (options.localURL || 'http://coderunner.local:8222')\n : (options.baseURL || 'https://api.instavm.io'),\n timeout: this.timeout,\n maxRetries: options.maxRetries || 3,\n retryDelay: options.retryDelay || 1000,\n apiKey: apiKey || '',\n };\n\n this.httpClient = new HTTPClient(config);\n this.browser = new BrowserManager(this.httpClient, this.local);\n }\n\n /**\n * Ensure operation is not called in local mode\n */\n private ensureNotLocal(operationName: string): void {\n if (this.local) {\n throw new UnsupportedOperationError(\n `${operationName} is not supported in local mode. This operation is only available when using the cloud API.`\n );\n }\n }\n\n /**\n * Execute code synchronously\n *\n * @param command - Command to execute\n * @param options - Execution options\n * @param options.timeout - Request timeout in milliseconds (used for HTTP request timeout and sent to API in seconds)\n * @returns Execution result\n */\n async execute(\n command: string,\n options: ExecuteOptions = {}\n ): Promise<ExecutionResult> {\n // In local mode, session_id is not required\n let sessionId = options.sessionId || this._sessionId;\n if (!this.local && !sessionId) {\n sessionId = await this.createSession();\n }\n\n const requestData: any = {\n command,\n language: options.language || 'python',\n };\n\n // Add timeout to request data if provided (convert milliseconds to seconds for API)\n if (options.timeout !== undefined) {\n requestData.timeout = Math.floor(options.timeout / 1000);\n }\n\n // Only include session_id in cloud mode\n if (!this.local && sessionId) {\n requestData.session_id = sessionId;\n }\n\n // Use custom timeout for this request, or fall back to instance default (in milliseconds)\n const requestTimeout = options.timeout !== undefined ? options.timeout : this.timeout;\n\n try {\n const response = await this.httpClient.postExecution<any>(\n '/execute',\n requestData,\n undefined,\n requestTimeout\n );\n\n // Update session ID if returned\n if (response.session_id) {\n this._sessionId = response.session_id;\n }\n\n return {\n output: response.stdout || response.output || '',\n success: response.success !== false,\n executionTime: response.execution_time || 0,\n sessionId: response.session_id,\n error: response.error,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new ExecutionError(\n `Code execution failed: ${errorMessage}`,\n undefined,\n undefined,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Execute code asynchronously\n */\n async executeAsync(\n command: string,\n options: ExecuteOptions = {}\n ): Promise<AsyncExecutionResult> {\n this.ensureNotLocal('Async execution');\n\n // Auto-create session if none exists (like Python client)\n let sessionId = options.sessionId || this._sessionId;\n if (!sessionId) {\n sessionId = await this.createSession();\n }\n\n const requestData = {\n command,\n language: options.language || 'python',\n timeout: options.timeout || 15,\n session_id: sessionId,\n };\n\n try {\n const response = await this.httpClient.postExecution<any>(\n '/execute_async',\n requestData\n );\n\n // Update session ID if returned\n if (response.session_id) {\n this._sessionId = response.session_id;\n }\n\n return {\n taskId: response.task_id,\n status: response.status || 'pending',\n output: response.stdout || response.output,\n success: response.success,\n executionTime: response.execution_time,\n sessionId: response.session_id,\n error: response.error,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new ExecutionError(\n `Async code execution failed: ${errorMessage}`,\n undefined,\n undefined,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Upload files to the execution environment\n */\n async upload(\n files: FileUpload[],\n options: UploadOptions = {}\n ): Promise<UploadResult> {\n this.ensureNotLocal('File upload');\n const formData = new FormData();\n\n // Add files to form data\n for (const file of files) {\n if (Buffer.isBuffer(file.content)) {\n formData.append('files', file.content, file.name);\n } else {\n formData.append('files', Buffer.from(file.content), file.name);\n }\n \n if (file.path) {\n formData.append('paths', file.path);\n }\n }\n\n // Add options\n if (options.sessionId || this._sessionId) {\n formData.append('session_id', options.sessionId || this._sessionId!);\n }\n if (options.remotePath) {\n formData.append('remote_path', options.remotePath);\n }\n if (options.recursive !== undefined) {\n formData.append('recursive', String(options.recursive));\n }\n\n try {\n const response = await this.httpClient.postFormData<any>(\n '/upload',\n formData\n );\n\n return {\n success: response.success !== false,\n files: response.files || [],\n message: response.message,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `File upload failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Create a new execution session\n */\n async createSession(): Promise<string> {\n this.ensureNotLocal('Session management');\n\n try {\n // Send API key and VM lifetime in JSON body for session creation\n // Convert timeout from milliseconds to seconds for the API\n const response = await this.httpClient.post<any>('/v1/sessions/session', {\n api_key: this.httpClient.apiKey,\n vm_lifetime_seconds: Math.floor(this.timeout / 1000)\n });\n\n if (response.session_id) {\n this._sessionId = response.session_id;\n return response.session_id;\n }\n\n throw new SessionError('Session creation failed: No session ID returned');\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `Session creation failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Close a session\n */\n async closeSession(sessionId?: string): Promise<void> {\n const targetSessionId = sessionId || this._sessionId;\n \n if (!targetSessionId) {\n return; // No session to close\n }\n\n try {\n await this.httpClient.delete(`/v1/sessions/${targetSessionId}`);\n \n if (targetSessionId === this._sessionId) {\n this._sessionId = null;\n }\n } catch (error) {\n // Don't throw on session close errors - session might already be expired\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.warn(`Failed to close session ${targetSessionId}:`, errorMessage);\n }\n }\n\n /**\n * Get usage statistics for a session\n */\n async getUsage(sessionId?: string): Promise<UsageStats> {\n this.ensureNotLocal('Usage tracking');\n\n const targetSessionId = sessionId || this._sessionId;\n\n if (!targetSessionId) {\n throw new SessionError('No active session to get usage for');\n }\n\n try {\n const response = await this.httpClient.get<any>(\n `/v1/sessions/usage/${targetSessionId}`\n );\n\n return {\n sessionsUsed: response.sessions_used || 0,\n executionTime: response.execution_time || 0,\n quotaRemaining: response.quota_remaining || 0,\n quotaLimit: response.quota_limit || 0,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `Failed to get usage stats: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Download a file from the remote VM\n */\n async download(\n filename: string,\n options: DownloadOptions = {}\n ): Promise<DownloadResult> {\n this.ensureNotLocal('File download');\n\n const targetSessionId = options.sessionId || this._sessionId;\n\n if (!targetSessionId) {\n throw new SessionError('No active session to download from');\n }\n\n try {\n const response = await this.httpClient.postRaw('/download', {\n filename,\n session_id: targetSessionId,\n });\n\n const content = Buffer.from(response);\n\n return {\n success: true,\n filename,\n content,\n size: content.length,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `File download failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Get the current session ID\n */\n get sessionId(): string | null {\n return this._sessionId;\n }\n\n /**\n * Clean up resources\n */\n async dispose(): Promise<void> {\n if (this._sessionId) {\n await this.closeSession();\n }\n await this.browser.dispose();\n }\n}"],"mappings":"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","names":["axios","FormData"]}
|
package/dist/index.mjs
CHANGED
|
@@ -227,18 +227,19 @@ var HTTPClient = class {
|
|
|
227
227
|
/**
|
|
228
228
|
* POST request with JSON body
|
|
229
229
|
*/
|
|
230
|
-
async post(url, data, headers) {
|
|
230
|
+
async post(url, data, headers, timeout) {
|
|
231
231
|
return this.request({
|
|
232
232
|
method: "POST",
|
|
233
233
|
url,
|
|
234
234
|
data,
|
|
235
|
-
headers
|
|
235
|
+
headers,
|
|
236
|
+
timeout
|
|
236
237
|
});
|
|
237
238
|
}
|
|
238
239
|
/**
|
|
239
240
|
* POST request for code execution (uses X-API-Key header like Python client)
|
|
240
241
|
*/
|
|
241
|
-
async postExecution(url, data, headers) {
|
|
242
|
+
async postExecution(url, data, headers, timeout) {
|
|
242
243
|
const requestHeaders = {
|
|
243
244
|
"X-API-Key": this.config.apiKey,
|
|
244
245
|
...headers
|
|
@@ -247,7 +248,8 @@ var HTTPClient = class {
|
|
|
247
248
|
method: "POST",
|
|
248
249
|
url,
|
|
249
250
|
data,
|
|
250
|
-
headers: requestHeaders
|
|
251
|
+
headers: requestHeaders,
|
|
252
|
+
timeout
|
|
251
253
|
});
|
|
252
254
|
}
|
|
253
255
|
/**
|
|
@@ -858,13 +860,13 @@ var InstaVM = class {
|
|
|
858
860
|
constructor(apiKey, options = {}) {
|
|
859
861
|
this._sessionId = null;
|
|
860
862
|
this.local = options.local || false;
|
|
863
|
+
this.timeout = options.timeout || 3e5;
|
|
861
864
|
if (!this.local && !apiKey) {
|
|
862
865
|
throw new AuthenticationError("API key is required for cloud mode");
|
|
863
866
|
}
|
|
864
867
|
const config = {
|
|
865
868
|
baseURL: this.local ? options.localURL || "http://coderunner.local:8222" : options.baseURL || "https://api.instavm.io",
|
|
866
|
-
timeout:
|
|
867
|
-
// 5 minutes
|
|
869
|
+
timeout: this.timeout,
|
|
868
870
|
maxRetries: options.maxRetries || 3,
|
|
869
871
|
retryDelay: options.retryDelay || 1e3,
|
|
870
872
|
apiKey: apiKey || ""
|
|
@@ -884,6 +886,11 @@ var InstaVM = class {
|
|
|
884
886
|
}
|
|
885
887
|
/**
|
|
886
888
|
* Execute code synchronously
|
|
889
|
+
*
|
|
890
|
+
* @param command - Command to execute
|
|
891
|
+
* @param options - Execution options
|
|
892
|
+
* @param options.timeout - Request timeout in milliseconds (used for HTTP request timeout and sent to API in seconds)
|
|
893
|
+
* @returns Execution result
|
|
887
894
|
*/
|
|
888
895
|
async execute(command, options = {}) {
|
|
889
896
|
let sessionId = options.sessionId || this._sessionId;
|
|
@@ -892,16 +899,21 @@ var InstaVM = class {
|
|
|
892
899
|
}
|
|
893
900
|
const requestData = {
|
|
894
901
|
command,
|
|
895
|
-
language: options.language || "python"
|
|
896
|
-
timeout: options.timeout || 15
|
|
902
|
+
language: options.language || "python"
|
|
897
903
|
};
|
|
904
|
+
if (options.timeout !== void 0) {
|
|
905
|
+
requestData.timeout = Math.floor(options.timeout / 1e3);
|
|
906
|
+
}
|
|
898
907
|
if (!this.local && sessionId) {
|
|
899
908
|
requestData.session_id = sessionId;
|
|
900
909
|
}
|
|
910
|
+
const requestTimeout = options.timeout !== void 0 ? options.timeout : this.timeout;
|
|
901
911
|
try {
|
|
902
912
|
const response = await this.httpClient.postExecution(
|
|
903
913
|
"/execute",
|
|
904
|
-
requestData
|
|
914
|
+
requestData,
|
|
915
|
+
void 0,
|
|
916
|
+
requestTimeout
|
|
905
917
|
);
|
|
906
918
|
if (response.session_id) {
|
|
907
919
|
this._sessionId = response.session_id;
|
|
@@ -1015,7 +1027,8 @@ var InstaVM = class {
|
|
|
1015
1027
|
this.ensureNotLocal("Session management");
|
|
1016
1028
|
try {
|
|
1017
1029
|
const response = await this.httpClient.post("/v1/sessions/session", {
|
|
1018
|
-
api_key: this.httpClient.apiKey
|
|
1030
|
+
api_key: this.httpClient.apiKey,
|
|
1031
|
+
vm_lifetime_seconds: Math.floor(this.timeout / 1e3)
|
|
1019
1032
|
});
|
|
1020
1033
|
if (response.session_id) {
|
|
1021
1034
|
this._sessionId = response.session_id;
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/HTTPClient.ts","../src/errors/BaseError.ts","../src/utils/retry.ts","../src/client/BrowserSession.ts","../src/client/BrowserManager.ts","../src/client/InstaVM.ts"],"sourcesContent":["import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';\nimport FormData from 'form-data';\nimport {\n InstaVMError,\n AuthenticationError,\n RateLimitError,\n QuotaExceededError,\n NetworkError,\n} from '../errors/BaseError';\nimport { withRetry } from '../utils/retry';\nimport type { HttpClientConfig, RequestConfig } from '../types/api';\n\n/**\n * HTTP client with authentication, retry logic, and error handling\n */\nexport class HTTPClient {\n private client: AxiosInstance;\n private config: HttpClientConfig;\n\n get apiKey(): string {\n return this.config.apiKey;\n }\n\n constructor(config: HttpClientConfig) {\n this.config = config;\n \n this.client = axios.create({\n baseURL: config.baseURL,\n timeout: config.timeout,\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'instavm-js-sdk/0.1.0',\n },\n });\n\n this.setupInterceptors();\n }\n\n private setupInterceptors(): void {\n // Request interceptor - add authentication\n this.client.interceptors.request.use(\n (config) => {\n // Add API key to headers for browser endpoints\n if (config.url?.includes('/browser/')) {\n config.headers['X-API-Key'] = this.config.apiKey;\n }\n \n return config;\n },\n (error) => Promise.reject(error)\n );\n\n // Response interceptor - handle errors\n this.client.interceptors.response.use(\n (response) => response,\n (error) => {\n const axiosError = error;\n const status = axiosError.response?.status;\n const data = axiosError.response?.data;\n const message = data?.message || data?.error || axiosError.message;\n\n switch (status) {\n case 401:\n throw new AuthenticationError(message, {\n statusCode: status,\n response: data,\n });\n case 402:\n throw new QuotaExceededError(message, {\n statusCode: status,\n response: data,\n });\n case 429:\n const retryAfter = parseInt(\n axiosError.response?.headers['retry-after'] || '60'\n );\n throw new RateLimitError(message, retryAfter, {\n statusCode: status,\n response: data,\n });\n case 500:\n case 502:\n case 503:\n case 504:\n throw new NetworkError(message, {\n statusCode: status,\n response: data,\n });\n default:\n if (axiosError.code === 'ECONNABORTED') {\n throw new NetworkError('Request timeout', {\n code: axiosError.code,\n });\n }\n throw new InstaVMError(message, {\n statusCode: status,\n response: data,\n code: axiosError.code,\n });\n }\n }\n );\n }\n\n /**\n * Make an HTTP request with retry logic\n */\n async request<T = any>(requestConfig: RequestConfig): Promise<T> {\n const axiosConfig: AxiosRequestConfig = {\n method: requestConfig.method,\n url: requestConfig.url,\n headers: requestConfig.headers,\n data: requestConfig.data,\n params: requestConfig.params,\n timeout: requestConfig.timeout || this.config.timeout,\n };\n\n const makeRequest = async (): Promise<T> => {\n const response: AxiosResponse<T> = await this.client.request(axiosConfig);\n return response.data;\n };\n\n return withRetry(makeRequest, {\n retries: this.config.maxRetries,\n retryDelay: this.config.retryDelay,\n });\n }\n\n /**\n * POST request with JSON body\n */\n async post<T = any>(\n url: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>({\n method: 'POST',\n url,\n data,\n headers,\n });\n }\n\n /**\n * POST request for code execution (uses X-API-Key header like Python client)\n */\n async postExecution<T = any>(\n url: string,\n data: any,\n headers?: Record<string, string>\n ): Promise<T> {\n const requestHeaders = {\n 'X-API-Key': this.config.apiKey,\n ...headers,\n };\n\n return this.request<T>({\n method: 'POST',\n url,\n data,\n headers: requestHeaders,\n });\n }\n\n /**\n * POST request with form data (for file uploads)\n */\n async postFormData<T = any>(\n url: string,\n formData: FormData,\n headers?: Record<string, string>\n ): Promise<T> {\n const requestHeaders = {\n ...formData.getHeaders(),\n ...headers,\n };\n\n return this.request<T>({\n method: 'POST',\n url,\n data: formData,\n headers: requestHeaders,\n });\n }\n\n /**\n * GET request\n */\n async get<T = any>(\n url: string,\n params?: Record<string, any>,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>({\n method: 'GET',\n url,\n params,\n headers,\n });\n }\n\n /**\n * DELETE request\n */\n async delete<T = any>(\n url: string,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>({\n method: 'DELETE',\n url,\n headers,\n });\n }\n\n /**\n * POST request that returns raw binary data (for file downloads)\n */\n async postRaw(\n url: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<ArrayBuffer> {\n const requestHeaders = {\n 'X-API-Key': this.config.apiKey,\n ...headers,\n };\n\n const axiosConfig: AxiosRequestConfig = {\n method: 'POST',\n url,\n data,\n headers: requestHeaders,\n responseType: 'arraybuffer',\n timeout: this.config.timeout,\n };\n\n const makeRequest = async (): Promise<ArrayBuffer> => {\n const response: AxiosResponse<ArrayBuffer> = await this.client.request(axiosConfig);\n return response.data;\n };\n\n return withRetry(makeRequest, {\n retries: this.config.maxRetries,\n retryDelay: this.config.retryDelay,\n });\n }\n}","/**\n * Base error class for all InstaVM SDK errors\n */\nexport class InstaVMError extends Error {\n public readonly name: string;\n public readonly code?: string;\n public readonly statusCode?: number;\n public readonly response?: any;\n\n constructor(\n message: string,\n options?: {\n code?: string;\n statusCode?: number;\n response?: any;\n cause?: Error;\n }\n ) {\n super(message);\n this.name = this.constructor.name;\n this.code = options?.code;\n this.statusCode = options?.statusCode;\n this.response = options?.response;\n\n // Ensure proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n\n // Capture stack trace, excluding constructor call from it\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Authentication-related errors (401, invalid API key, etc.)\n */\nexport class AuthenticationError extends InstaVMError {\n constructor(message: string = 'Authentication failed', options?: any) {\n super(message, { ...options, statusCode: 401 });\n }\n}\n\n/**\n * Rate limiting errors (429)\n */\nexport class RateLimitError extends InstaVMError {\n public readonly retryAfter?: number;\n\n constructor(\n message: string = 'Rate limit exceeded',\n retryAfter?: number,\n options?: any\n ) {\n super(message, { ...options, statusCode: 429 });\n this.retryAfter = retryAfter;\n }\n}\n\n/**\n * Quota/usage limit exceeded errors\n */\nexport class QuotaExceededError extends InstaVMError {\n constructor(message: string = 'Usage quota exceeded', options?: any) {\n super(message, { ...options, statusCode: 402 });\n }\n}\n\n/**\n * Network-related errors (timeouts, connection issues, 5xx errors)\n */\nexport class NetworkError extends InstaVMError {\n constructor(message: string = 'Network error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Code execution errors\n */\nexport class ExecutionError extends InstaVMError {\n public readonly executionOutput?: string;\n public readonly executionTime?: number;\n\n constructor(\n message: string,\n executionOutput?: string,\n executionTime?: number,\n options?: any\n ) {\n super(message, options);\n this.executionOutput = executionOutput;\n this.executionTime = executionTime;\n }\n}\n\n/**\n * Session management errors\n */\nexport class SessionError extends InstaVMError {\n constructor(message: string = 'Session error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser automation base error\n */\nexport class BrowserError extends InstaVMError {\n constructor(message: string = 'Browser error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser session management errors\n */\nexport class BrowserSessionError extends BrowserError {\n constructor(message: string = 'Browser session error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser interaction errors (click, type, etc.)\n */\nexport class BrowserInteractionError extends BrowserError {\n constructor(message: string = 'Browser interaction error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser timeout errors\n */\nexport class BrowserTimeoutError extends BrowserError {\n constructor(message: string = 'Browser operation timed out', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser navigation errors\n */\nexport class BrowserNavigationError extends BrowserError {\n constructor(message: string = 'Browser navigation error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Element not found errors\n */\nexport class ElementNotFoundError extends BrowserError {\n public readonly selector?: string;\n\n constructor(\n message: string = 'Element not found',\n selector?: string,\n options?: any\n ) {\n super(message, options);\n this.selector = selector;\n }\n}\n\n/**\n * Unsupported operation error (e.g., operations not available in local mode)\n */\nexport class UnsupportedOperationError extends InstaVMError {\n constructor(message: string = 'Operation not supported', options?: any) {\n super(message, options);\n }\n}","import { NetworkError, RateLimitError } from '../errors/BaseError';\n\nexport interface RetryOptions {\n retries: number;\n retryDelay: number;\n maxRetryDelay?: number;\n retryCondition?: (error: any) => boolean;\n}\n\n/**\n * Default retry condition - retry on network errors and 5xx server errors\n */\nexport function defaultRetryCondition(error: any): boolean {\n if (error instanceof NetworkError) return true;\n if (error instanceof RateLimitError) return true;\n \n // Axios error with status code\n if (error.response?.status >= 500) return true;\n \n // Network/timeout errors\n if (error.code === 'ECONNABORTED' || error.code === 'ETIMEDOUT') return true;\n if (error.code === 'ECONNRESET' || error.code === 'ENOTFOUND') return true;\n \n return false;\n}\n\n/**\n * Calculate exponential backoff delay\n */\nexport function calculateRetryDelay(\n attempt: number,\n baseDelay: number,\n maxDelay = 30000\n): number {\n const exponentialDelay = baseDelay * Math.pow(2, attempt - 1);\n const jitteredDelay = exponentialDelay * (0.5 + Math.random() * 0.5);\n return Math.min(jitteredDelay, maxDelay);\n}\n\n/**\n * Retry a function with exponential backoff\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions\n): Promise<T> {\n const {\n retries,\n retryDelay,\n maxRetryDelay = 30000,\n retryCondition = defaultRetryCondition,\n } = options;\n\n let lastError: any;\n\n for (let attempt = 1; attempt <= retries + 1; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n\n // Don't retry on last attempt\n if (attempt === retries + 1) {\n break;\n }\n\n // Check if we should retry this error\n if (!retryCondition(error)) {\n break;\n }\n\n // Calculate delay for this attempt\n const delay = calculateRetryDelay(attempt, retryDelay, maxRetryDelay);\n \n // Wait before retrying\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n\n throw lastError;\n}","import { EventEmitter } from 'eventemitter3';\nimport type { HTTPClient } from './HTTPClient';\nimport {\n BrowserError,\n BrowserInteractionError,\n BrowserNavigationError,\n BrowserTimeoutError,\n ElementNotFoundError,\n} from '../errors/BaseError';\nimport type {\n NavigateOptions,\n NavigationResult,\n ClickOptions,\n TypeOptions,\n FillOptions,\n ScrollOptions,\n ScreenshotOptions,\n WaitCondition,\n ExtractedElement,\n ExtractOptions,\n ExtractContentOptions,\n ExtractedContent,\n} from '../types/browser';\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * Browser session for automation\n */\nexport class BrowserSession extends EventEmitter {\n public readonly sessionId: string;\n private httpClient: HTTPClient;\n private _isActive: boolean = true;\n\n constructor(sessionId: string, httpClient: HTTPClient) {\n super();\n this.sessionId = sessionId;\n this.httpClient = httpClient;\n }\n\n /**\n * Navigate to a URL\n */\n async navigate(\n url: string,\n options: NavigateOptions = {}\n ): Promise<NavigationResult> {\n this.ensureActive();\n\n const requestData = {\n url,\n session_id: this.sessionId,\n wait_timeout: options.waitTimeout || 30000,\n wait_until: options.waitUntil || 'load',\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/navigate',\n requestData\n );\n\n const result: NavigationResult = {\n success: response.success !== false,\n url: response.url || url,\n title: response.title,\n status: response.status,\n };\n\n this.emit('navigation', result);\n return result;\n } catch (error) {\n const navigationError = new BrowserNavigationError(\n `Navigation failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n this.emit('error', navigationError);\n throw navigationError;\n }\n }\n\n /**\n * Click an element\n */\n async click(selector: string, options: ClickOptions = {}): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n selector,\n session_id: this.sessionId,\n timeout: options.timeout || 10000,\n button: options.button || 'left',\n click_count: options.clickCount || 1,\n force: options.force || false,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/click',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('not found') || errorMessage.includes('selector')) {\n throw new ElementNotFoundError(\n `Element not found: ${selector}`,\n selector,\n { cause: error as Error }\n );\n }\n if (errorMessage.includes('timeout')) {\n throw new BrowserTimeoutError(\n `Click timeout: ${selector}`,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Click failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Type text into an element\n */\n async type(\n selector: string,\n text: string,\n options: TypeOptions = {}\n ): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n selector,\n text,\n session_id: this.sessionId,\n timeout: options.timeout || 10000,\n delay: options.delay || 0,\n clear: options.clear !== false,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/type',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('not found') || errorMessage.includes('selector')) {\n throw new ElementNotFoundError(\n `Element not found: ${selector}`,\n selector,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Type failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Fill a form field\n */\n async fill(\n selector: string,\n value: string,\n options: FillOptions = {}\n ): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n selector,\n value,\n session_id: this.sessionId,\n timeout: options.timeout || 10000,\n force: options.force || false,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/fill',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('not found') || errorMessage.includes('selector')) {\n throw new ElementNotFoundError(\n `Element not found: ${selector}`,\n selector,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Fill failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Scroll the page\n */\n async scroll(options: ScrollOptions = {}): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n session_id: this.sessionId,\n x: options.x || 0,\n y: options.y || 500,\n behavior: options.behavior || 'auto',\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/scroll',\n requestData\n );\n } catch (error) {\n throw new BrowserInteractionError(\n `Scroll failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Take a screenshot\n */\n async screenshot(options: ScreenshotOptions = {}): Promise<string> {\n this.ensureActive();\n\n const requestData = {\n session_id: this.sessionId,\n full_page: options.fullPage !== false,\n format: options.format || 'png',\n quality: options.quality || 90,\n clip: options.clip,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/screenshot',\n requestData\n );\n\n if (!response.screenshot) {\n throw new BrowserError('Screenshot data not returned');\n }\n\n return response.screenshot;\n } catch (error) {\n throw new BrowserInteractionError(\n `Screenshot failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Extract elements from the page\n */\n async extractElements(\n selector: string,\n attributes: string[] = ['text'],\n options: ExtractOptions = {}\n ): Promise<ExtractedElement[]> {\n this.ensureActive();\n\n const requestData = {\n selector,\n attributes,\n session_id: this.sessionId,\n max_results: options.maxResults || 100,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/extract',\n requestData\n );\n\n return response.elements || [];\n } catch (error) {\n throw new BrowserInteractionError(\n `Element extraction failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Extract LLM-friendly content from the current page\n *\n * Returns clean article content, interactive elements, and content anchors\n * for intelligent browser automation with LLMs.\n *\n * @param options - Content extraction options\n * @returns Extracted content with readable text, interactive elements, and content anchors\n *\n * @example\n * ```typescript\n * const content = await session.extractContent();\n *\n * // LLM reads clean content\n * const article = content.readableContent.content;\n *\n * // LLM finds \"Sign Up\" in content and uses anchors to get selector\n * const signUpAnchor = content.contentAnchors?.find(\n * anchor => anchor.text.toLowerCase().includes('sign up')\n * );\n * if (signUpAnchor) {\n * await session.click(signUpAnchor.selector);\n * }\n * ```\n */\n async extractContent(\n options: ExtractContentOptions = {}\n ): Promise<ExtractedContent> {\n this.ensureActive();\n\n const requestData = {\n session_id: this.sessionId,\n include_interactive: options.includeInteractive !== false,\n include_anchors: options.includeAnchors !== false,\n max_anchors: options.maxAnchors ?? 50,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/content',\n requestData\n );\n\n return {\n readableContent: {\n ...(response.readable_content || {}),\n content: response.readable_content?.content || '',\n },\n interactiveElements: response.interactive_elements,\n contentAnchors: response.content_anchors,\n };\n } catch (error) {\n throw new BrowserInteractionError(\n `Content extraction failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Wait for a condition\n */\n async wait(condition: WaitCondition, timeout = 10000): Promise<void> {\n this.ensureActive();\n\n let requestData: any = {\n session_id: this.sessionId,\n timeout,\n };\n\n if (condition.type === 'timeout') {\n // Simple timeout wait\n await new Promise(resolve => setTimeout(resolve, condition.ms));\n return;\n }\n\n requestData = {\n ...requestData,\n condition: condition.type,\n selector: 'selector' in condition ? condition.selector : undefined,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/wait',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('timeout')) {\n throw new BrowserTimeoutError(\n `Wait condition timeout: ${condition.type}`,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Wait failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Close the browser session\n */\n async close(): Promise<void> {\n if (!this._isActive) {\n return;\n }\n\n try {\n await this.httpClient.delete(`/v1/browser/sessions/${this.sessionId}`);\n } catch (error) {\n // Don't throw on close errors - session might already be closed\n console.warn(`Failed to close browser session ${this.sessionId}:`, getErrorMessage(error));\n } finally {\n this._isActive = false;\n this.emit('close');\n }\n }\n\n /**\n * Check if session is active\n */\n get isActive(): boolean {\n return this._isActive;\n }\n\n /**\n * Ensure session is active before operations\n */\n private ensureActive(): void {\n if (!this._isActive) {\n throw new BrowserError('Browser session is not active');\n }\n }\n}","import type { HTTPClient } from './HTTPClient';\nimport { BrowserSession } from './BrowserSession';\nimport { BrowserSessionError, BrowserNavigationError, BrowserInteractionError, UnsupportedOperationError } from '../errors/BaseError';\nimport type {\n BrowserSessionOptions,\n BrowserSessionInfo,\n NavigateOptions,\n NavigationResult,\n ExtractContentOptions,\n ExtractedContent,\n} from '../types/browser';\n\n/**\n * Browser automation manager\n */\nexport class BrowserManager {\n private httpClient: HTTPClient;\n private activeSessions: Map<string, BrowserSession> = new Map();\n private local: boolean;\n\n constructor(httpClient: HTTPClient, local: boolean = false) {\n this.httpClient = httpClient;\n this.local = local;\n }\n\n /**\n * Create a new browser session\n */\n async createSession(\n options: BrowserSessionOptions = {}\n ): Promise<BrowserSession> {\n if (this.local) {\n throw new UnsupportedOperationError(\n 'Browser session management is not supported in local mode. Use navigate() or extractContent() with URL directly.'\n );\n }\n\n const requestData = {\n viewport_width: options.viewportWidth || 1920,\n viewport_height: options.viewportHeight || 1080,\n user_agent: options.userAgent,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/sessions/',\n requestData\n );\n\n if (!response.session_id) {\n throw new BrowserSessionError('No session ID returned from server');\n }\n\n const session = new BrowserSession(response.session_id, this.httpClient);\n this.activeSessions.set(response.session_id, session);\n\n // Clean up session from our tracking when it's closed\n session.on('close', () => {\n this.activeSessions.delete(response.session_id);\n });\n\n return session;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserSessionError(\n `Failed to create browser session: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Get information about a specific session\n */\n async getSession(sessionId: string): Promise<BrowserSessionInfo> {\n try {\n const response = await this.httpClient.get<any>(\n `/v1/browser/sessions/${sessionId}`\n );\n\n return {\n sessionId: response.session_id,\n status: response.status || 'active',\n createdAt: response.created_at,\n viewportWidth: response.viewport_width,\n viewportHeight: response.viewport_height,\n userAgent: response.user_agent,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserSessionError(\n `Failed to get session info: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * List all browser sessions\n */\n async listSessions(): Promise<BrowserSessionInfo[]> {\n try {\n const response = await this.httpClient.get<any>('/v1/browser/sessions/');\n\n if (!Array.isArray(response.sessions)) {\n return [];\n }\n\n return response.sessions.map((session: any) => ({\n sessionId: session.session_id,\n status: session.status || 'active',\n createdAt: session.created_at,\n viewportWidth: session.viewport_width,\n viewportHeight: session.viewport_height,\n userAgent: session.user_agent,\n }));\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserSessionError(\n `Failed to list sessions: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Get a locally tracked session\n */\n getLocalSession(sessionId: string): BrowserSession | undefined {\n return this.activeSessions.get(sessionId);\n }\n\n /**\n * Get all locally tracked sessions\n */\n getLocalSessions(): BrowserSession[] {\n return Array.from(this.activeSessions.values());\n }\n\n /**\n * Close all active sessions\n */\n async closeAllSessions(): Promise<void> {\n const sessions = Array.from(this.activeSessions.values());\n \n await Promise.allSettled(\n sessions.map(session => session.close())\n );\n \n this.activeSessions.clear();\n }\n\n /**\n * Navigate to a URL (local mode support - no session required)\n */\n async navigate(\n url: string,\n options: NavigateOptions = {}\n ): Promise<NavigationResult> {\n if (!this.local) {\n throw new UnsupportedOperationError(\n 'navigate() without session is only supported in local mode. In cloud mode, create a session first.'\n );\n }\n\n const requestData = {\n url,\n wait_timeout: options.waitTimeout || 30000,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/navigate',\n requestData\n );\n\n return {\n success: response.success !== false,\n url: response.url || url,\n title: response.title,\n status: response.status,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserNavigationError(\n `Navigation failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Extract LLM-friendly content (local mode support - no session required)\n */\n async extractContent(\n options: ExtractContentOptions = {}\n ): Promise<ExtractedContent> {\n if (!this.local) {\n throw new UnsupportedOperationError(\n 'extractContent() without session is only supported in local mode. In cloud mode, create a session first.'\n );\n }\n\n if (!options.url) {\n throw new BrowserInteractionError('url is required in local mode');\n }\n\n const requestData = {\n url: options.url,\n include_interactive: options.includeInteractive !== false,\n include_anchors: options.includeAnchors !== false,\n max_anchors: options.maxAnchors ?? 50,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/content',\n requestData\n );\n\n return {\n readableContent: {\n ...(response.readable_content || {}),\n content: response.readable_content?.content || '',\n },\n interactiveElements: response.interactive_elements,\n contentAnchors: response.content_anchors,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserInteractionError(\n `Content extraction failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Clean up resources\n */\n async dispose(): Promise<void> {\n await this.closeAllSessions();\n }\n}","import { HTTPClient } from './HTTPClient';\nimport { BrowserManager } from './BrowserManager';\nimport FormData from 'form-data';\nimport { SessionError, ExecutionError, UnsupportedOperationError, AuthenticationError } from '../errors/BaseError';\nimport type {\n ExecuteOptions,\n ExecutionResult,\n AsyncExecutionResult,\n FileUpload,\n UploadOptions,\n UploadResult,\n UsageStats,\n DownloadOptions,\n DownloadResult,\n} from '../types/execution';\n\nexport interface InstaVMOptions {\n baseURL?: string;\n timeout?: number;\n maxRetries?: number;\n retryDelay?: number;\n local?: boolean;\n localURL?: string;\n}\n\n/**\n * Main InstaVM client class\n */\nexport class InstaVM {\n private httpClient: HTTPClient;\n private _sessionId: string | null = null;\n public readonly browser: BrowserManager;\n public readonly local: boolean;\n\n constructor(apiKey: string, options: InstaVMOptions = {}) {\n this.local = options.local || false;\n\n // In local mode, API key is optional\n if (!this.local && !apiKey) {\n throw new AuthenticationError('API key is required for cloud mode');\n }\n\n const config = {\n baseURL: this.local\n ? (options.localURL || 'http://coderunner.local:8222')\n : (options.baseURL || 'https://api.instavm.io'),\n timeout: options.timeout || 300000, // 5 minutes\n maxRetries: options.maxRetries || 3,\n retryDelay: options.retryDelay || 1000,\n apiKey: apiKey || '',\n };\n\n this.httpClient = new HTTPClient(config);\n this.browser = new BrowserManager(this.httpClient, this.local);\n }\n\n /**\n * Ensure operation is not called in local mode\n */\n private ensureNotLocal(operationName: string): void {\n if (this.local) {\n throw new UnsupportedOperationError(\n `${operationName} is not supported in local mode. This operation is only available when using the cloud API.`\n );\n }\n }\n\n /**\n * Execute code synchronously\n */\n async execute(\n command: string,\n options: ExecuteOptions = {}\n ): Promise<ExecutionResult> {\n // In local mode, session_id is not required\n let sessionId = options.sessionId || this._sessionId;\n if (!this.local && !sessionId) {\n sessionId = await this.createSession();\n }\n\n const requestData: any = {\n command,\n language: options.language || 'python',\n timeout: options.timeout || 15,\n };\n\n // Only include session_id in cloud mode\n if (!this.local && sessionId) {\n requestData.session_id = sessionId;\n }\n\n try {\n const response = await this.httpClient.postExecution<any>(\n '/execute',\n requestData\n );\n\n // Update session ID if returned\n if (response.session_id) {\n this._sessionId = response.session_id;\n }\n\n return {\n output: response.stdout || response.output || '',\n success: response.success !== false,\n executionTime: response.execution_time || 0,\n sessionId: response.session_id,\n error: response.error,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new ExecutionError(\n `Code execution failed: ${errorMessage}`,\n undefined,\n undefined,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Execute code asynchronously\n */\n async executeAsync(\n command: string,\n options: ExecuteOptions = {}\n ): Promise<AsyncExecutionResult> {\n this.ensureNotLocal('Async execution');\n\n // Auto-create session if none exists (like Python client)\n let sessionId = options.sessionId || this._sessionId;\n if (!sessionId) {\n sessionId = await this.createSession();\n }\n\n const requestData = {\n command,\n language: options.language || 'python',\n timeout: options.timeout || 15,\n session_id: sessionId,\n };\n\n try {\n const response = await this.httpClient.postExecution<any>(\n '/execute_async',\n requestData\n );\n\n // Update session ID if returned\n if (response.session_id) {\n this._sessionId = response.session_id;\n }\n\n return {\n taskId: response.task_id,\n status: response.status || 'pending',\n output: response.stdout || response.output,\n success: response.success,\n executionTime: response.execution_time,\n sessionId: response.session_id,\n error: response.error,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new ExecutionError(\n `Async code execution failed: ${errorMessage}`,\n undefined,\n undefined,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Upload files to the execution environment\n */\n async upload(\n files: FileUpload[],\n options: UploadOptions = {}\n ): Promise<UploadResult> {\n this.ensureNotLocal('File upload');\n const formData = new FormData();\n\n // Add files to form data\n for (const file of files) {\n if (Buffer.isBuffer(file.content)) {\n formData.append('files', file.content, file.name);\n } else {\n formData.append('files', Buffer.from(file.content), file.name);\n }\n \n if (file.path) {\n formData.append('paths', file.path);\n }\n }\n\n // Add options\n if (options.sessionId || this._sessionId) {\n formData.append('session_id', options.sessionId || this._sessionId!);\n }\n if (options.remotePath) {\n formData.append('remote_path', options.remotePath);\n }\n if (options.recursive !== undefined) {\n formData.append('recursive', String(options.recursive));\n }\n\n try {\n const response = await this.httpClient.postFormData<any>(\n '/upload',\n formData\n );\n\n return {\n success: response.success !== false,\n files: response.files || [],\n message: response.message,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `File upload failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Create a new execution session\n */\n async createSession(): Promise<string> {\n this.ensureNotLocal('Session management');\n\n try {\n // Send API key in JSON body for session creation (like Python client)\n const response = await this.httpClient.post<any>('/v1/sessions/session', {\n api_key: this.httpClient.apiKey\n });\n\n if (response.session_id) {\n this._sessionId = response.session_id;\n return response.session_id;\n }\n\n throw new SessionError('Session creation failed: No session ID returned');\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `Session creation failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Close a session\n */\n async closeSession(sessionId?: string): Promise<void> {\n const targetSessionId = sessionId || this._sessionId;\n \n if (!targetSessionId) {\n return; // No session to close\n }\n\n try {\n await this.httpClient.delete(`/v1/sessions/${targetSessionId}`);\n \n if (targetSessionId === this._sessionId) {\n this._sessionId = null;\n }\n } catch (error) {\n // Don't throw on session close errors - session might already be expired\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.warn(`Failed to close session ${targetSessionId}:`, errorMessage);\n }\n }\n\n /**\n * Get usage statistics for a session\n */\n async getUsage(sessionId?: string): Promise<UsageStats> {\n this.ensureNotLocal('Usage tracking');\n\n const targetSessionId = sessionId || this._sessionId;\n\n if (!targetSessionId) {\n throw new SessionError('No active session to get usage for');\n }\n\n try {\n const response = await this.httpClient.get<any>(\n `/v1/sessions/usage/${targetSessionId}`\n );\n\n return {\n sessionsUsed: response.sessions_used || 0,\n executionTime: response.execution_time || 0,\n quotaRemaining: response.quota_remaining || 0,\n quotaLimit: response.quota_limit || 0,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `Failed to get usage stats: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Download a file from the remote VM\n */\n async download(\n filename: string,\n options: DownloadOptions = {}\n ): Promise<DownloadResult> {\n this.ensureNotLocal('File download');\n\n const targetSessionId = options.sessionId || this._sessionId;\n\n if (!targetSessionId) {\n throw new SessionError('No active session to download from');\n }\n\n try {\n const response = await this.httpClient.postRaw('/download', {\n filename,\n session_id: targetSessionId,\n });\n\n const content = Buffer.from(response);\n\n return {\n success: true,\n filename,\n content,\n size: content.length,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `File download failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Get the current session ID\n */\n get sessionId(): string | null {\n return this._sessionId;\n }\n\n /**\n * Clean up resources\n */\n async dispose(): Promise<void> {\n if (this._sessionId) {\n await this.closeSession();\n }\n await this.browser.dispose();\n }\n}"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/client/HTTPClient.ts","../src/errors/BaseError.ts","../src/utils/retry.ts","../src/client/BrowserSession.ts","../src/client/BrowserManager.ts","../src/client/InstaVM.ts"],"sourcesContent":["import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';\nimport FormData from 'form-data';\nimport {\n InstaVMError,\n AuthenticationError,\n RateLimitError,\n QuotaExceededError,\n NetworkError,\n} from '../errors/BaseError';\nimport { withRetry } from '../utils/retry';\nimport type { HttpClientConfig, RequestConfig } from '../types/api';\n\n/**\n * HTTP client with authentication, retry logic, and error handling\n */\nexport class HTTPClient {\n private client: AxiosInstance;\n private config: HttpClientConfig;\n\n get apiKey(): string {\n return this.config.apiKey;\n }\n\n constructor(config: HttpClientConfig) {\n this.config = config;\n \n this.client = axios.create({\n baseURL: config.baseURL,\n timeout: config.timeout,\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'instavm-js-sdk/0.1.0',\n },\n });\n\n this.setupInterceptors();\n }\n\n private setupInterceptors(): void {\n // Request interceptor - add authentication\n this.client.interceptors.request.use(\n (config) => {\n // Add API key to headers for browser endpoints\n if (config.url?.includes('/browser/')) {\n config.headers['X-API-Key'] = this.config.apiKey;\n }\n \n return config;\n },\n (error) => Promise.reject(error)\n );\n\n // Response interceptor - handle errors\n this.client.interceptors.response.use(\n (response) => response,\n (error) => {\n const axiosError = error;\n const status = axiosError.response?.status;\n const data = axiosError.response?.data;\n const message = data?.message || data?.error || axiosError.message;\n\n switch (status) {\n case 401:\n throw new AuthenticationError(message, {\n statusCode: status,\n response: data,\n });\n case 402:\n throw new QuotaExceededError(message, {\n statusCode: status,\n response: data,\n });\n case 429:\n const retryAfter = parseInt(\n axiosError.response?.headers['retry-after'] || '60'\n );\n throw new RateLimitError(message, retryAfter, {\n statusCode: status,\n response: data,\n });\n case 500:\n case 502:\n case 503:\n case 504:\n throw new NetworkError(message, {\n statusCode: status,\n response: data,\n });\n default:\n if (axiosError.code === 'ECONNABORTED') {\n throw new NetworkError('Request timeout', {\n code: axiosError.code,\n });\n }\n throw new InstaVMError(message, {\n statusCode: status,\n response: data,\n code: axiosError.code,\n });\n }\n }\n );\n }\n\n /**\n * Make an HTTP request with retry logic\n */\n async request<T = any>(requestConfig: RequestConfig): Promise<T> {\n const axiosConfig: AxiosRequestConfig = {\n method: requestConfig.method,\n url: requestConfig.url,\n headers: requestConfig.headers,\n data: requestConfig.data,\n params: requestConfig.params,\n timeout: requestConfig.timeout || this.config.timeout,\n };\n\n const makeRequest = async (): Promise<T> => {\n const response: AxiosResponse<T> = await this.client.request(axiosConfig);\n return response.data;\n };\n\n return withRetry(makeRequest, {\n retries: this.config.maxRetries,\n retryDelay: this.config.retryDelay,\n });\n }\n\n /**\n * POST request with JSON body\n */\n async post<T = any>(\n url: string,\n data?: any,\n headers?: Record<string, string>,\n timeout?: number\n ): Promise<T> {\n return this.request<T>({\n method: 'POST',\n url,\n data,\n headers,\n timeout,\n });\n }\n\n /**\n * POST request for code execution (uses X-API-Key header like Python client)\n */\n async postExecution<T = any>(\n url: string,\n data: any,\n headers?: Record<string, string>,\n timeout?: number\n ): Promise<T> {\n const requestHeaders = {\n 'X-API-Key': this.config.apiKey,\n ...headers,\n };\n\n return this.request<T>({\n method: 'POST',\n url,\n data,\n headers: requestHeaders,\n timeout,\n });\n }\n\n /**\n * POST request with form data (for file uploads)\n */\n async postFormData<T = any>(\n url: string,\n formData: FormData,\n headers?: Record<string, string>\n ): Promise<T> {\n const requestHeaders = {\n ...formData.getHeaders(),\n ...headers,\n };\n\n return this.request<T>({\n method: 'POST',\n url,\n data: formData,\n headers: requestHeaders,\n });\n }\n\n /**\n * GET request\n */\n async get<T = any>(\n url: string,\n params?: Record<string, any>,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>({\n method: 'GET',\n url,\n params,\n headers,\n });\n }\n\n /**\n * DELETE request\n */\n async delete<T = any>(\n url: string,\n headers?: Record<string, string>\n ): Promise<T> {\n return this.request<T>({\n method: 'DELETE',\n url,\n headers,\n });\n }\n\n /**\n * POST request that returns raw binary data (for file downloads)\n */\n async postRaw(\n url: string,\n data?: any,\n headers?: Record<string, string>\n ): Promise<ArrayBuffer> {\n const requestHeaders = {\n 'X-API-Key': this.config.apiKey,\n ...headers,\n };\n\n const axiosConfig: AxiosRequestConfig = {\n method: 'POST',\n url,\n data,\n headers: requestHeaders,\n responseType: 'arraybuffer',\n timeout: this.config.timeout,\n };\n\n const makeRequest = async (): Promise<ArrayBuffer> => {\n const response: AxiosResponse<ArrayBuffer> = await this.client.request(axiosConfig);\n return response.data;\n };\n\n return withRetry(makeRequest, {\n retries: this.config.maxRetries,\n retryDelay: this.config.retryDelay,\n });\n }\n}","/**\n * Base error class for all InstaVM SDK errors\n */\nexport class InstaVMError extends Error {\n public readonly name: string;\n public readonly code?: string;\n public readonly statusCode?: number;\n public readonly response?: any;\n\n constructor(\n message: string,\n options?: {\n code?: string;\n statusCode?: number;\n response?: any;\n cause?: Error;\n }\n ) {\n super(message);\n this.name = this.constructor.name;\n this.code = options?.code;\n this.statusCode = options?.statusCode;\n this.response = options?.response;\n\n // Ensure proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n\n // Capture stack trace, excluding constructor call from it\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Authentication-related errors (401, invalid API key, etc.)\n */\nexport class AuthenticationError extends InstaVMError {\n constructor(message: string = 'Authentication failed', options?: any) {\n super(message, { ...options, statusCode: 401 });\n }\n}\n\n/**\n * Rate limiting errors (429)\n */\nexport class RateLimitError extends InstaVMError {\n public readonly retryAfter?: number;\n\n constructor(\n message: string = 'Rate limit exceeded',\n retryAfter?: number,\n options?: any\n ) {\n super(message, { ...options, statusCode: 429 });\n this.retryAfter = retryAfter;\n }\n}\n\n/**\n * Quota/usage limit exceeded errors\n */\nexport class QuotaExceededError extends InstaVMError {\n constructor(message: string = 'Usage quota exceeded', options?: any) {\n super(message, { ...options, statusCode: 402 });\n }\n}\n\n/**\n * Network-related errors (timeouts, connection issues, 5xx errors)\n */\nexport class NetworkError extends InstaVMError {\n constructor(message: string = 'Network error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Code execution errors\n */\nexport class ExecutionError extends InstaVMError {\n public readonly executionOutput?: string;\n public readonly executionTime?: number;\n\n constructor(\n message: string,\n executionOutput?: string,\n executionTime?: number,\n options?: any\n ) {\n super(message, options);\n this.executionOutput = executionOutput;\n this.executionTime = executionTime;\n }\n}\n\n/**\n * Session management errors\n */\nexport class SessionError extends InstaVMError {\n constructor(message: string = 'Session error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser automation base error\n */\nexport class BrowserError extends InstaVMError {\n constructor(message: string = 'Browser error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser session management errors\n */\nexport class BrowserSessionError extends BrowserError {\n constructor(message: string = 'Browser session error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser interaction errors (click, type, etc.)\n */\nexport class BrowserInteractionError extends BrowserError {\n constructor(message: string = 'Browser interaction error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser timeout errors\n */\nexport class BrowserTimeoutError extends BrowserError {\n constructor(message: string = 'Browser operation timed out', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Browser navigation errors\n */\nexport class BrowserNavigationError extends BrowserError {\n constructor(message: string = 'Browser navigation error', options?: any) {\n super(message, options);\n }\n}\n\n/**\n * Element not found errors\n */\nexport class ElementNotFoundError extends BrowserError {\n public readonly selector?: string;\n\n constructor(\n message: string = 'Element not found',\n selector?: string,\n options?: any\n ) {\n super(message, options);\n this.selector = selector;\n }\n}\n\n/**\n * Unsupported operation error (e.g., operations not available in local mode)\n */\nexport class UnsupportedOperationError extends InstaVMError {\n constructor(message: string = 'Operation not supported', options?: any) {\n super(message, options);\n }\n}","import { NetworkError, RateLimitError } from '../errors/BaseError';\n\nexport interface RetryOptions {\n retries: number;\n retryDelay: number;\n maxRetryDelay?: number;\n retryCondition?: (error: any) => boolean;\n}\n\n/**\n * Default retry condition - retry on network errors and 5xx server errors\n */\nexport function defaultRetryCondition(error: any): boolean {\n if (error instanceof NetworkError) return true;\n if (error instanceof RateLimitError) return true;\n \n // Axios error with status code\n if (error.response?.status >= 500) return true;\n \n // Network/timeout errors\n if (error.code === 'ECONNABORTED' || error.code === 'ETIMEDOUT') return true;\n if (error.code === 'ECONNRESET' || error.code === 'ENOTFOUND') return true;\n \n return false;\n}\n\n/**\n * Calculate exponential backoff delay\n */\nexport function calculateRetryDelay(\n attempt: number,\n baseDelay: number,\n maxDelay = 30000\n): number {\n const exponentialDelay = baseDelay * Math.pow(2, attempt - 1);\n const jitteredDelay = exponentialDelay * (0.5 + Math.random() * 0.5);\n return Math.min(jitteredDelay, maxDelay);\n}\n\n/**\n * Retry a function with exponential backoff\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions\n): Promise<T> {\n const {\n retries,\n retryDelay,\n maxRetryDelay = 30000,\n retryCondition = defaultRetryCondition,\n } = options;\n\n let lastError: any;\n\n for (let attempt = 1; attempt <= retries + 1; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n\n // Don't retry on last attempt\n if (attempt === retries + 1) {\n break;\n }\n\n // Check if we should retry this error\n if (!retryCondition(error)) {\n break;\n }\n\n // Calculate delay for this attempt\n const delay = calculateRetryDelay(attempt, retryDelay, maxRetryDelay);\n \n // Wait before retrying\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n\n throw lastError;\n}","import { EventEmitter } from 'eventemitter3';\nimport type { HTTPClient } from './HTTPClient';\nimport {\n BrowserError,\n BrowserInteractionError,\n BrowserNavigationError,\n BrowserTimeoutError,\n ElementNotFoundError,\n} from '../errors/BaseError';\nimport type {\n NavigateOptions,\n NavigationResult,\n ClickOptions,\n TypeOptions,\n FillOptions,\n ScrollOptions,\n ScreenshotOptions,\n WaitCondition,\n ExtractedElement,\n ExtractOptions,\n ExtractContentOptions,\n ExtractedContent,\n} from '../types/browser';\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * Browser session for automation\n */\nexport class BrowserSession extends EventEmitter {\n public readonly sessionId: string;\n private httpClient: HTTPClient;\n private _isActive: boolean = true;\n\n constructor(sessionId: string, httpClient: HTTPClient) {\n super();\n this.sessionId = sessionId;\n this.httpClient = httpClient;\n }\n\n /**\n * Navigate to a URL\n */\n async navigate(\n url: string,\n options: NavigateOptions = {}\n ): Promise<NavigationResult> {\n this.ensureActive();\n\n const requestData = {\n url,\n session_id: this.sessionId,\n wait_timeout: options.waitTimeout || 30000,\n wait_until: options.waitUntil || 'load',\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/navigate',\n requestData\n );\n\n const result: NavigationResult = {\n success: response.success !== false,\n url: response.url || url,\n title: response.title,\n status: response.status,\n };\n\n this.emit('navigation', result);\n return result;\n } catch (error) {\n const navigationError = new BrowserNavigationError(\n `Navigation failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n this.emit('error', navigationError);\n throw navigationError;\n }\n }\n\n /**\n * Click an element\n */\n async click(selector: string, options: ClickOptions = {}): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n selector,\n session_id: this.sessionId,\n timeout: options.timeout || 10000,\n button: options.button || 'left',\n click_count: options.clickCount || 1,\n force: options.force || false,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/click',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('not found') || errorMessage.includes('selector')) {\n throw new ElementNotFoundError(\n `Element not found: ${selector}`,\n selector,\n { cause: error as Error }\n );\n }\n if (errorMessage.includes('timeout')) {\n throw new BrowserTimeoutError(\n `Click timeout: ${selector}`,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Click failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Type text into an element\n */\n async type(\n selector: string,\n text: string,\n options: TypeOptions = {}\n ): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n selector,\n text,\n session_id: this.sessionId,\n timeout: options.timeout || 10000,\n delay: options.delay || 0,\n clear: options.clear !== false,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/type',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('not found') || errorMessage.includes('selector')) {\n throw new ElementNotFoundError(\n `Element not found: ${selector}`,\n selector,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Type failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Fill a form field\n */\n async fill(\n selector: string,\n value: string,\n options: FillOptions = {}\n ): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n selector,\n value,\n session_id: this.sessionId,\n timeout: options.timeout || 10000,\n force: options.force || false,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/fill',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('not found') || errorMessage.includes('selector')) {\n throw new ElementNotFoundError(\n `Element not found: ${selector}`,\n selector,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Fill failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Scroll the page\n */\n async scroll(options: ScrollOptions = {}): Promise<void> {\n this.ensureActive();\n\n const requestData = {\n session_id: this.sessionId,\n x: options.x || 0,\n y: options.y || 500,\n behavior: options.behavior || 'auto',\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/scroll',\n requestData\n );\n } catch (error) {\n throw new BrowserInteractionError(\n `Scroll failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Take a screenshot\n */\n async screenshot(options: ScreenshotOptions = {}): Promise<string> {\n this.ensureActive();\n\n const requestData = {\n session_id: this.sessionId,\n full_page: options.fullPage !== false,\n format: options.format || 'png',\n quality: options.quality || 90,\n clip: options.clip,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/screenshot',\n requestData\n );\n\n if (!response.screenshot) {\n throw new BrowserError('Screenshot data not returned');\n }\n\n return response.screenshot;\n } catch (error) {\n throw new BrowserInteractionError(\n `Screenshot failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Extract elements from the page\n */\n async extractElements(\n selector: string,\n attributes: string[] = ['text'],\n options: ExtractOptions = {}\n ): Promise<ExtractedElement[]> {\n this.ensureActive();\n\n const requestData = {\n selector,\n attributes,\n session_id: this.sessionId,\n max_results: options.maxResults || 100,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/extract',\n requestData\n );\n\n return response.elements || [];\n } catch (error) {\n throw new BrowserInteractionError(\n `Element extraction failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Extract LLM-friendly content from the current page\n *\n * Returns clean article content, interactive elements, and content anchors\n * for intelligent browser automation with LLMs.\n *\n * @param options - Content extraction options\n * @returns Extracted content with readable text, interactive elements, and content anchors\n *\n * @example\n * ```typescript\n * const content = await session.extractContent();\n *\n * // LLM reads clean content\n * const article = content.readableContent.content;\n *\n * // LLM finds \"Sign Up\" in content and uses anchors to get selector\n * const signUpAnchor = content.contentAnchors?.find(\n * anchor => anchor.text.toLowerCase().includes('sign up')\n * );\n * if (signUpAnchor) {\n * await session.click(signUpAnchor.selector);\n * }\n * ```\n */\n async extractContent(\n options: ExtractContentOptions = {}\n ): Promise<ExtractedContent> {\n this.ensureActive();\n\n const requestData = {\n session_id: this.sessionId,\n include_interactive: options.includeInteractive !== false,\n include_anchors: options.includeAnchors !== false,\n max_anchors: options.maxAnchors ?? 50,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/content',\n requestData\n );\n\n return {\n readableContent: {\n ...(response.readable_content || {}),\n content: response.readable_content?.content || '',\n },\n interactiveElements: response.interactive_elements,\n contentAnchors: response.content_anchors,\n };\n } catch (error) {\n throw new BrowserInteractionError(\n `Content extraction failed: ${getErrorMessage(error)}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Wait for a condition\n */\n async wait(condition: WaitCondition, timeout = 10000): Promise<void> {\n this.ensureActive();\n\n let requestData: any = {\n session_id: this.sessionId,\n timeout,\n };\n\n if (condition.type === 'timeout') {\n // Simple timeout wait\n await new Promise(resolve => setTimeout(resolve, condition.ms));\n return;\n }\n\n requestData = {\n ...requestData,\n condition: condition.type,\n selector: 'selector' in condition ? condition.selector : undefined,\n };\n\n try {\n await this.httpClient.post<any>(\n '/v1/browser/interactions/wait',\n requestData\n );\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n if (errorMessage.includes('timeout')) {\n throw new BrowserTimeoutError(\n `Wait condition timeout: ${condition.type}`,\n { cause: error as Error }\n );\n }\n throw new BrowserInteractionError(\n `Wait failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Close the browser session\n */\n async close(): Promise<void> {\n if (!this._isActive) {\n return;\n }\n\n try {\n await this.httpClient.delete(`/v1/browser/sessions/${this.sessionId}`);\n } catch (error) {\n // Don't throw on close errors - session might already be closed\n console.warn(`Failed to close browser session ${this.sessionId}:`, getErrorMessage(error));\n } finally {\n this._isActive = false;\n this.emit('close');\n }\n }\n\n /**\n * Check if session is active\n */\n get isActive(): boolean {\n return this._isActive;\n }\n\n /**\n * Ensure session is active before operations\n */\n private ensureActive(): void {\n if (!this._isActive) {\n throw new BrowserError('Browser session is not active');\n }\n }\n}","import type { HTTPClient } from './HTTPClient';\nimport { BrowserSession } from './BrowserSession';\nimport { BrowserSessionError, BrowserNavigationError, BrowserInteractionError, UnsupportedOperationError } from '../errors/BaseError';\nimport type {\n BrowserSessionOptions,\n BrowserSessionInfo,\n NavigateOptions,\n NavigationResult,\n ExtractContentOptions,\n ExtractedContent,\n} from '../types/browser';\n\n/**\n * Browser automation manager\n */\nexport class BrowserManager {\n private httpClient: HTTPClient;\n private activeSessions: Map<string, BrowserSession> = new Map();\n private local: boolean;\n\n constructor(httpClient: HTTPClient, local: boolean = false) {\n this.httpClient = httpClient;\n this.local = local;\n }\n\n /**\n * Create a new browser session\n */\n async createSession(\n options: BrowserSessionOptions = {}\n ): Promise<BrowserSession> {\n if (this.local) {\n throw new UnsupportedOperationError(\n 'Browser session management is not supported in local mode. Use navigate() or extractContent() with URL directly.'\n );\n }\n\n const requestData = {\n viewport_width: options.viewportWidth || 1920,\n viewport_height: options.viewportHeight || 1080,\n user_agent: options.userAgent,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/sessions/',\n requestData\n );\n\n if (!response.session_id) {\n throw new BrowserSessionError('No session ID returned from server');\n }\n\n const session = new BrowserSession(response.session_id, this.httpClient);\n this.activeSessions.set(response.session_id, session);\n\n // Clean up session from our tracking when it's closed\n session.on('close', () => {\n this.activeSessions.delete(response.session_id);\n });\n\n return session;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserSessionError(\n `Failed to create browser session: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Get information about a specific session\n */\n async getSession(sessionId: string): Promise<BrowserSessionInfo> {\n try {\n const response = await this.httpClient.get<any>(\n `/v1/browser/sessions/${sessionId}`\n );\n\n return {\n sessionId: response.session_id,\n status: response.status || 'active',\n createdAt: response.created_at,\n viewportWidth: response.viewport_width,\n viewportHeight: response.viewport_height,\n userAgent: response.user_agent,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserSessionError(\n `Failed to get session info: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * List all browser sessions\n */\n async listSessions(): Promise<BrowserSessionInfo[]> {\n try {\n const response = await this.httpClient.get<any>('/v1/browser/sessions/');\n\n if (!Array.isArray(response.sessions)) {\n return [];\n }\n\n return response.sessions.map((session: any) => ({\n sessionId: session.session_id,\n status: session.status || 'active',\n createdAt: session.created_at,\n viewportWidth: session.viewport_width,\n viewportHeight: session.viewport_height,\n userAgent: session.user_agent,\n }));\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserSessionError(\n `Failed to list sessions: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Get a locally tracked session\n */\n getLocalSession(sessionId: string): BrowserSession | undefined {\n return this.activeSessions.get(sessionId);\n }\n\n /**\n * Get all locally tracked sessions\n */\n getLocalSessions(): BrowserSession[] {\n return Array.from(this.activeSessions.values());\n }\n\n /**\n * Close all active sessions\n */\n async closeAllSessions(): Promise<void> {\n const sessions = Array.from(this.activeSessions.values());\n \n await Promise.allSettled(\n sessions.map(session => session.close())\n );\n \n this.activeSessions.clear();\n }\n\n /**\n * Navigate to a URL (local mode support - no session required)\n */\n async navigate(\n url: string,\n options: NavigateOptions = {}\n ): Promise<NavigationResult> {\n if (!this.local) {\n throw new UnsupportedOperationError(\n 'navigate() without session is only supported in local mode. In cloud mode, create a session first.'\n );\n }\n\n const requestData = {\n url,\n wait_timeout: options.waitTimeout || 30000,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/navigate',\n requestData\n );\n\n return {\n success: response.success !== false,\n url: response.url || url,\n title: response.title,\n status: response.status,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserNavigationError(\n `Navigation failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Extract LLM-friendly content (local mode support - no session required)\n */\n async extractContent(\n options: ExtractContentOptions = {}\n ): Promise<ExtractedContent> {\n if (!this.local) {\n throw new UnsupportedOperationError(\n 'extractContent() without session is only supported in local mode. In cloud mode, create a session first.'\n );\n }\n\n if (!options.url) {\n throw new BrowserInteractionError('url is required in local mode');\n }\n\n const requestData = {\n url: options.url,\n include_interactive: options.includeInteractive !== false,\n include_anchors: options.includeAnchors !== false,\n max_anchors: options.maxAnchors ?? 50,\n };\n\n try {\n const response = await this.httpClient.post<any>(\n '/v1/browser/interactions/content',\n requestData\n );\n\n return {\n readableContent: {\n ...(response.readable_content || {}),\n content: response.readable_content?.content || '',\n },\n interactiveElements: response.interactive_elements,\n contentAnchors: response.content_anchors,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new BrowserInteractionError(\n `Content extraction failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Clean up resources\n */\n async dispose(): Promise<void> {\n await this.closeAllSessions();\n }\n}","import { HTTPClient } from './HTTPClient';\nimport { BrowserManager } from './BrowserManager';\nimport FormData from 'form-data';\nimport { SessionError, ExecutionError, UnsupportedOperationError, AuthenticationError } from '../errors/BaseError';\nimport type {\n ExecuteOptions,\n ExecutionResult,\n AsyncExecutionResult,\n FileUpload,\n UploadOptions,\n UploadResult,\n UsageStats,\n DownloadOptions,\n DownloadResult,\n} from '../types/execution';\n\nexport interface InstaVMOptions {\n baseURL?: string;\n /**\n * Timeout in milliseconds. Used for HTTP request timeout and sent to API as VM lifetime (in seconds).\n * Default: 300000 (5 minutes)\n */\n timeout?: number;\n maxRetries?: number;\n retryDelay?: number;\n local?: boolean;\n localURL?: string;\n}\n\n/**\n * Main InstaVM client class\n */\nexport class InstaVM {\n private httpClient: HTTPClient;\n private _sessionId: string | null = null;\n public readonly browser: BrowserManager;\n public readonly local: boolean;\n private readonly timeout: number;\n\n constructor(apiKey: string, options: InstaVMOptions = {}) {\n this.local = options.local || false;\n this.timeout = options.timeout || 300000; // 300000 milliseconds (5 minutes)\n\n // In local mode, API key is optional\n if (!this.local && !apiKey) {\n throw new AuthenticationError('API key is required for cloud mode');\n }\n\n const config = {\n baseURL: this.local\n ? (options.localURL || 'http://coderunner.local:8222')\n : (options.baseURL || 'https://api.instavm.io'),\n timeout: this.timeout,\n maxRetries: options.maxRetries || 3,\n retryDelay: options.retryDelay || 1000,\n apiKey: apiKey || '',\n };\n\n this.httpClient = new HTTPClient(config);\n this.browser = new BrowserManager(this.httpClient, this.local);\n }\n\n /**\n * Ensure operation is not called in local mode\n */\n private ensureNotLocal(operationName: string): void {\n if (this.local) {\n throw new UnsupportedOperationError(\n `${operationName} is not supported in local mode. This operation is only available when using the cloud API.`\n );\n }\n }\n\n /**\n * Execute code synchronously\n *\n * @param command - Command to execute\n * @param options - Execution options\n * @param options.timeout - Request timeout in milliseconds (used for HTTP request timeout and sent to API in seconds)\n * @returns Execution result\n */\n async execute(\n command: string,\n options: ExecuteOptions = {}\n ): Promise<ExecutionResult> {\n // In local mode, session_id is not required\n let sessionId = options.sessionId || this._sessionId;\n if (!this.local && !sessionId) {\n sessionId = await this.createSession();\n }\n\n const requestData: any = {\n command,\n language: options.language || 'python',\n };\n\n // Add timeout to request data if provided (convert milliseconds to seconds for API)\n if (options.timeout !== undefined) {\n requestData.timeout = Math.floor(options.timeout / 1000);\n }\n\n // Only include session_id in cloud mode\n if (!this.local && sessionId) {\n requestData.session_id = sessionId;\n }\n\n // Use custom timeout for this request, or fall back to instance default (in milliseconds)\n const requestTimeout = options.timeout !== undefined ? options.timeout : this.timeout;\n\n try {\n const response = await this.httpClient.postExecution<any>(\n '/execute',\n requestData,\n undefined,\n requestTimeout\n );\n\n // Update session ID if returned\n if (response.session_id) {\n this._sessionId = response.session_id;\n }\n\n return {\n output: response.stdout || response.output || '',\n success: response.success !== false,\n executionTime: response.execution_time || 0,\n sessionId: response.session_id,\n error: response.error,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new ExecutionError(\n `Code execution failed: ${errorMessage}`,\n undefined,\n undefined,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Execute code asynchronously\n */\n async executeAsync(\n command: string,\n options: ExecuteOptions = {}\n ): Promise<AsyncExecutionResult> {\n this.ensureNotLocal('Async execution');\n\n // Auto-create session if none exists (like Python client)\n let sessionId = options.sessionId || this._sessionId;\n if (!sessionId) {\n sessionId = await this.createSession();\n }\n\n const requestData = {\n command,\n language: options.language || 'python',\n timeout: options.timeout || 15,\n session_id: sessionId,\n };\n\n try {\n const response = await this.httpClient.postExecution<any>(\n '/execute_async',\n requestData\n );\n\n // Update session ID if returned\n if (response.session_id) {\n this._sessionId = response.session_id;\n }\n\n return {\n taskId: response.task_id,\n status: response.status || 'pending',\n output: response.stdout || response.output,\n success: response.success,\n executionTime: response.execution_time,\n sessionId: response.session_id,\n error: response.error,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new ExecutionError(\n `Async code execution failed: ${errorMessage}`,\n undefined,\n undefined,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Upload files to the execution environment\n */\n async upload(\n files: FileUpload[],\n options: UploadOptions = {}\n ): Promise<UploadResult> {\n this.ensureNotLocal('File upload');\n const formData = new FormData();\n\n // Add files to form data\n for (const file of files) {\n if (Buffer.isBuffer(file.content)) {\n formData.append('files', file.content, file.name);\n } else {\n formData.append('files', Buffer.from(file.content), file.name);\n }\n \n if (file.path) {\n formData.append('paths', file.path);\n }\n }\n\n // Add options\n if (options.sessionId || this._sessionId) {\n formData.append('session_id', options.sessionId || this._sessionId!);\n }\n if (options.remotePath) {\n formData.append('remote_path', options.remotePath);\n }\n if (options.recursive !== undefined) {\n formData.append('recursive', String(options.recursive));\n }\n\n try {\n const response = await this.httpClient.postFormData<any>(\n '/upload',\n formData\n );\n\n return {\n success: response.success !== false,\n files: response.files || [],\n message: response.message,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `File upload failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Create a new execution session\n */\n async createSession(): Promise<string> {\n this.ensureNotLocal('Session management');\n\n try {\n // Send API key and VM lifetime in JSON body for session creation\n // Convert timeout from milliseconds to seconds for the API\n const response = await this.httpClient.post<any>('/v1/sessions/session', {\n api_key: this.httpClient.apiKey,\n vm_lifetime_seconds: Math.floor(this.timeout / 1000)\n });\n\n if (response.session_id) {\n this._sessionId = response.session_id;\n return response.session_id;\n }\n\n throw new SessionError('Session creation failed: No session ID returned');\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `Session creation failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Close a session\n */\n async closeSession(sessionId?: string): Promise<void> {\n const targetSessionId = sessionId || this._sessionId;\n \n if (!targetSessionId) {\n return; // No session to close\n }\n\n try {\n await this.httpClient.delete(`/v1/sessions/${targetSessionId}`);\n \n if (targetSessionId === this._sessionId) {\n this._sessionId = null;\n }\n } catch (error) {\n // Don't throw on session close errors - session might already be expired\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.warn(`Failed to close session ${targetSessionId}:`, errorMessage);\n }\n }\n\n /**\n * Get usage statistics for a session\n */\n async getUsage(sessionId?: string): Promise<UsageStats> {\n this.ensureNotLocal('Usage tracking');\n\n const targetSessionId = sessionId || this._sessionId;\n\n if (!targetSessionId) {\n throw new SessionError('No active session to get usage for');\n }\n\n try {\n const response = await this.httpClient.get<any>(\n `/v1/sessions/usage/${targetSessionId}`\n );\n\n return {\n sessionsUsed: response.sessions_used || 0,\n executionTime: response.execution_time || 0,\n quotaRemaining: response.quota_remaining || 0,\n quotaLimit: response.quota_limit || 0,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `Failed to get usage stats: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Download a file from the remote VM\n */\n async download(\n filename: string,\n options: DownloadOptions = {}\n ): Promise<DownloadResult> {\n this.ensureNotLocal('File download');\n\n const targetSessionId = options.sessionId || this._sessionId;\n\n if (!targetSessionId) {\n throw new SessionError('No active session to download from');\n }\n\n try {\n const response = await this.httpClient.postRaw('/download', {\n filename,\n session_id: targetSessionId,\n });\n\n const content = Buffer.from(response);\n\n return {\n success: true,\n filename,\n content,\n size: content.length,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new SessionError(\n `File download failed: ${errorMessage}`,\n { cause: error as Error }\n );\n }\n }\n\n /**\n * Get the current session ID\n */\n get sessionId(): string | null {\n return this._sessionId;\n }\n\n /**\n * Clean up resources\n */\n async dispose(): Promise<void> {\n if (this._sessionId) {\n await this.closeSession();\n }\n await this.browser.dispose();\n }\n}"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "instavm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Official JavaScript SDK for InstaVM API",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"dev": "tsup --watch",
|
|
25
25
|
"build": "tsup",
|
|
26
26
|
"type-check": "tsc --noEmit",
|
|
27
|
-
"test": "vitest",
|
|
27
|
+
"test": "vitest run",
|
|
28
28
|
"test:unit": "vitest run tests/unit",
|
|
29
29
|
"test:integration": "vitest run tests/integration",
|
|
30
30
|
"test:watch": "vitest --watch",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"lint": "eslint src --ext .ts,.tsx",
|
|
33
33
|
"lint:fix": "eslint src --ext .ts,.tsx --fix",
|
|
34
34
|
"format": "prettier --write src/**/*.ts",
|
|
35
|
-
"prepublishOnly": "npm run build && npm run test",
|
|
35
|
+
"prepublishOnly": "npm run build && npm run test:unit",
|
|
36
36
|
"clean": "rm -rf dist"
|
|
37
37
|
},
|
|
38
38
|
"keywords": [
|