class TorcAPI {
constructor() {
this.baseUrl = '/torc-service/v1';
this.loadSettings();
}
loadSettings() {
const savedUrl = localStorage.getItem('torc-api-url');
if (savedUrl) {
this.baseUrl = savedUrl;
}
}
setBaseUrl(url) {
this.baseUrl = url;
localStorage.setItem('torc-api-url', url);
}
getBaseUrl() {
return this.baseUrl;
}
async request(endpoint, options = {}) {
const url = `${this.baseUrl}${endpoint}`;
const defaultOptions = {
headers: {
'Content-Type': 'application/json',
},
};
const finalOptions = {
...defaultOptions,
...options,
headers: {
...defaultOptions.headers,
...options.headers,
},
};
try {
const response = await fetch(url, finalOptions);
if (!response.ok) {
const errorText = await response.text();
throw new Error(`HTTP ${response.status}: ${errorText || response.statusText}`);
}
const text = await response.text();
if (!text) {
return null;
}
return JSON.parse(text);
} catch (error) {
console.error(`API Error (${endpoint}):`, error);
throw error;
}
}
extractItems(response) {
if (!response) return [];
if (Array.isArray(response)) return response;
if (response.items && Array.isArray(response.items)) return response.items;
return [];
}
async listWorkflows(offset = 0, limit = 100) {
const response = await this.request(`/workflows?offset=${offset}&limit=${limit}`);
return this.extractItems(response);
}
async getWorkflow(workflowId) {
return this.request(`/workflows/${workflowId}`);
}
async createWorkflow(workflow) {
return this.request('/workflows', {
method: 'POST',
body: JSON.stringify(workflow),
});
}
async deleteWorkflow(workflowId) {
return this.request(`/workflows/${workflowId}`, {
method: 'DELETE',
});
}
async getWorkflowStatus(workflowId) {
return this.request(`/workflows/${workflowId}/status`);
}
async initializeWorkflow(workflowId) {
return this.request(`/workflows/${workflowId}/initialize`, {
method: 'POST',
});
}
async listJobs(workflowId, offset = 0, limit = 10000) {
const response = await this.request(`/workflows/${workflowId}/jobs?offset=${offset}&limit=${limit}`);
return this.extractItems(response);
}
async getJob(jobId) {
return this.request(`/jobs/${jobId}`);
}
async updateJobStatus(jobId, status) {
return this.request(`/jobs/${jobId}`, {
method: 'PATCH',
body: JSON.stringify({ status }),
});
}
async getJobDependencies(jobId) {
return this.request(`/jobs/${jobId}/dependencies`);
}
async getJobsDependencies(workflowId) {
const response = await this.request(`/workflows/${workflowId}/jobs/dependencies`);
return this.extractItems(response);
}
async listFiles(workflowId, offset = 0, limit = 10000) {
const response = await this.request(`/workflows/${workflowId}/files?offset=${offset}&limit=${limit}`);
return this.extractItems(response);
}
async getFile(fileId) {
return this.request(`/files/${fileId}`);
}
async getJobFileRelationships(workflowId) {
const response = await this.request(`/workflows/${workflowId}/jobs/file_relationships`);
return this.extractItems(response);
}
async listUserData(workflowId, offset = 0, limit = 10000) {
const response = await this.request(`/workflows/${workflowId}/user_data?offset=${offset}&limit=${limit}`);
return this.extractItems(response);
}
async getUserData(userDataId) {
return this.request(`/user_data/${userDataId}`);
}
async getJobUserDataRelationships(workflowId) {
const response = await this.request(`/workflows/${workflowId}/jobs/user_data_relationships`);
return this.extractItems(response);
}
async listResults(workflowId, offset = 0, limit = 10000) {
const response = await this.request(`/workflows/${workflowId}/results?offset=${offset}&limit=${limit}`);
return this.extractItems(response);
}
async getResult(resultId) {
return this.request(`/results/${resultId}`);
}
async listEvents(workflowId = null, offset = 0, limit = 100, afterId = null) {
let url = '/events';
const params = new URLSearchParams();
if (workflowId) {
url = `/workflows/${workflowId}/events`;
}
params.set('offset', offset);
params.set('limit', limit);
if (afterId !== null) {
params.set('after_id', afterId);
}
const response = await this.request(`${url}?${params.toString()}`);
return this.extractItems(response);
}
async listComputeNodes(workflowId) {
return this.request(`/workflows/${workflowId}/compute_nodes`);
}
async listResourceRequirements(workflowId) {
return this.request(`/workflows/${workflowId}/resource_requirements`);
}
async listSchedulers(workflowId) {
return this.request(`/workflows/${workflowId}/schedulers`);
}
async testConnection() {
try {
await this.listWorkflows(0, 1);
return { success: true };
} catch (error) {
return { success: false, error: error.message };
}
}
}
const api = new TorcAPI();