import * as Data from "effect/Data";
import * as Effect from "effect/Effect";
import type { Env } from "./config.ts";
import type { InstallationParams } from "./installation-workflow.ts";
export class WorkflowUnavailable extends Data.TaggedError(
"WorkflowUnavailable",
)<{ missing: boolean }> {}
function native(call: () => Promise) {
return Effect.tryPromise({
try: call,
catch: (error) =>
new WorkflowUnavailable({
missing:
error instanceof Error &&
[
"instance.not_found",
"Error: instance.not_found",
"(instance.not_found) Instance not found",
].includes(error.message),
}),
});
}
export function terminateWorkflow(env: Env, id: string) {
return Effect.gen(function* () {
const instance = yield* native(() => env.INSTALLATION_WORKFLOW.get(id));
yield* native(() => instance.terminate());
if ((yield* native(() => instance.status())).status !== "terminated")
return yield* new WorkflowUnavailable({ missing: false });
});
}
// A lost create reply is reconciled against the same durable reservation.
export function ensureWorkflow(
env: Env,
id: string,
params: InstallationParams,
) {
return native(() => env.INSTALLATION_WORKFLOW.create({ id, params })).pipe(
Effect.asVoid,
Effect.catch(() =>
Effect.gen(function* () {
const instance = yield* native(() => env.INSTALLATION_WORKFLOW.get(id));
yield* native(() => instance.status());
}),
),
);
}