Skip to content
65 changes: 45 additions & 20 deletions src/blueapi/blueapi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { useQuery, UseQueryResult } from "react-query";

const BLUEAPI_SOCKET = import.meta.env.VITE_BLUEAPI_SOCKET;
const BLUEAPI_SOCKET: string = import.meta.env.VITE_BLUEAPI_SOCKET;

type BlueApiRequestBody = {
planName: string;
planParams: object;
};

export type BlueApiWorkerState =
| "IDLE"
| "RUNNING"
Expand All @@ -13,9 +19,14 @@ export type BlueApiWorkerState =
| "PANICKED"
| "UNKNOWN";

function blueApiCall(endpoint: string, method?: string, body?: object) {
function blueApiCall(
endpoint: string,
method?: string,
body?: object
): Promise<Response> {
const _method = method ?? "GET";
return fetch(BLUEAPI_SOCKET + endpoint, {
const fullUrl = BLUEAPI_SOCKET + endpoint;
return fetch(fullUrl, {
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Expand Down Expand Up @@ -60,27 +71,41 @@ export function getWorkerStatus(): Promise<BlueApiWorkerState> {
return blueApiCall("/worker/state").then((res) => res.json());
}

export function submitPlan(
planName: string,
planParams: object
): Promise<string> {
// Note. fetch only rejects a promise on network errors, but http errors
// must be caught by checking the response
function submitTask(request: BlueApiRequestBody): Promise<string | void> {
return blueApiCall("/tasks", "POST", {
name: planName,
params: planParams,
}).then((res) => res.json().then((res) => res["task_id"]));
name: request.planName,
params: request.planParams,
}).then((res) => {
if (!res.ok) {
throw new Error(
`Unable to POST request, response error ${res.statusText}`
);
}
res.json().then((res) => res["task_id"]);
});
}

function runTask(taskId: string): Promise<string | void> {
return blueApiCall("/worker/task", "PUT", { task_id: taskId }).then((res) => {
if (!res.ok) {
throw new Error(`Unable to run task, response error ${res.statusText}`);
}
res.json().then((res) => res["task_id"]);
});
}

export function submitAndRunPlanImmediately(
planName: string,
planParams: object
): Promise<string> {
return submitPlan(planName, planParams).then((res) =>
// TODO make sure submitPlan was succesful before then putting it to the worker
// See https://github.com/DiamondLightSource/mx-daq-ui/issues/17
blueApiCall("/worker/task", "PUT", { task_id: res }).then((res) =>
res.json().then((res) => res["task_id"])
)
);
request: BlueApiRequestBody
): Promise<string | void> {
return submitTask(request)
.then((res) => {
if (res) {
runTask(res);
}
})
.catch((error) => console.log(error));
}

export function abortCurrentPlan(): Promise<BlueApiWorkerState> {
Expand Down