@mochabug/adapt-web
Version:
The client library to execute automations, without effort, in a browser environment
164 lines • 5.89 kB
JavaScript
// Re-export from the new PubsubClient module
export * from "./pubsub-client.js";
// Default configuration
const defaultConfig = {
baseUrl: "https://adapt-dev.mochabugapis.com/v1/automations",
wsBaseUrl: "wss://adapt-dev.mochabugapis.com/v1/automations",
};
// Global configuration
let globalConfig = { ...defaultConfig };
// Configure the Adapt client
export function configure(config) {
globalConfig = { ...globalConfig, ...config };
}
// Get current configuration
export function getConfig() {
return { ...globalConfig };
}
// Reset to default configuration
export function resetConfig() {
globalConfig = { ...defaultConfig };
}
// Retry configuration
const RETRY_CONFIG = {
maxAttempts: 5,
initialDelay: 50, // 50ms
maxDelay: 5000, // 5 seconds
retryableStatusCodes: [429, 502, 503, 504], // Too Many Requests, Bad Gateway, Service Unavailable, Gateway Timeout
};
// Sleep helper
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
// Retry wrapper with exponential backoff
async function fetchWithRetry(url, options) {
let lastError;
for (let attempt = 1; attempt <= RETRY_CONFIG.maxAttempts; attempt++) {
try {
const response = await fetch(url, options);
if (response.ok) {
return response;
}
if (RETRY_CONFIG.retryableStatusCodes.includes(response.status)) {
lastError = new RestClientError(response);
if (attempt < RETRY_CONFIG.maxAttempts) {
const delay = Math.min(RETRY_CONFIG.initialDelay * Math.pow(2, attempt - 1), RETRY_CONFIG.maxDelay);
console.warn(`Request failed with ${response.status}, retrying in ${delay}ms (attempt ${attempt}/${RETRY_CONFIG.maxAttempts})`);
await sleep(delay);
continue;
}
}
throw new RestClientError(response);
}
catch (error) {
if (error instanceof RestClientError) {
throw error;
}
if (attempt < RETRY_CONFIG.maxAttempts) {
const delay = Math.min(RETRY_CONFIG.initialDelay * Math.pow(2, attempt - 1), RETRY_CONFIG.maxDelay);
console.warn(`Network error, retrying in ${delay}ms (attempt ${attempt}/${RETRY_CONFIG.maxAttempts})`, error);
await sleep(delay);
continue;
}
throw error;
}
}
throw lastError || new Error("All retry attempts failed");
}
// REST API functions
export async function startSession(req, token) {
const headers = new Headers({
"Content-Type": "application/json",
"Response-Type": "application/json",
});
if (token) {
headers.set("Authorization", `Bearer ${token}`);
}
const response = await fetchWithRetry(`${globalConfig.baseUrl}/${req.id}/session/start`, {
method: "POST",
body: JSON.stringify(req),
headers,
});
return await response.json();
}
export async function inheritSession(id, sessionToken) {
const response = await fetchWithRetry(`${globalConfig.baseUrl}/${id}/session/inherit`, {
method: "POST",
body: JSON.stringify({ id }),
headers: {
"Content-Type": "application/json",
"Response-Type": "application/json",
Authorization: `Bearer ${sessionToken}`,
},
});
return await response.json();
}
export async function getSession(id, sessionToken) {
const response = await fetchWithRetry(`${globalConfig.baseUrl}/${id}/session`, {
method: "GET",
headers: {
"Response-Type": "application/json",
Authorization: `Bearer ${sessionToken}`,
},
});
return await response.json();
}
export async function readOutput(id, sessionToken, options) {
const params = new URLSearchParams();
if (options?.pageSize !== undefined) {
params.set("page_size", options.pageSize.toString());
}
if (options?.vertex) {
params.set("vertex", options.vertex);
}
if (options?.newerThan) {
params.set("newer_than", options.newerThan);
}
const queryString = params.toString();
const url = `${globalConfig.baseUrl}/${id}/session/output${queryString ? `?${queryString}` : ""}`;
const response = await fetchWithRetry(url, {
method: "GET",
headers: {
"Response-Type": "application/json",
Authorization: `Bearer ${sessionToken}`,
},
});
return await response.json();
}
export async function readUrls(id, sessionToken, options) {
const params = new URLSearchParams();
if (options?.pageSize !== undefined) {
params.set("page_size", options.pageSize.toString());
}
if (options?.newerThan) {
params.set("newer_than", options.newerThan);
}
const queryString = params.toString();
const url = `${globalConfig.baseUrl}/${id}/session/urls${queryString ? `?${queryString}` : ""}`;
const response = await fetchWithRetry(url, {
method: "GET",
headers: {
"Response-Type": "application/json",
Authorization: `Bearer ${sessionToken}`,
},
});
return await response.json();
}
export async function stopSession(id, sessionToken) {
await fetchWithRetry(`${globalConfig.baseUrl}/${id}/session`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${sessionToken}`,
},
});
}
export class RestClientError extends Error {
constructor(response) {
super(`HTTP Error: ${response.status} ${response.statusText}`);
this.name = "RestClientError";
this.status = response.status;
this.statusText = response.statusText;
this.response = response;
}
}
//# sourceMappingURL=index.js.map