1import * as Effect from "effect/Effect";
2import type { Conflict } from "@distilled.cloud/prisma";
3import {
4 createDeploymentStart,
5 createDeploymentStop,
6} from "@distilled.cloud/prisma/management";
7import { observeDeployment } from "./DeploymentObserve.ts";
8
9const startConflictIsIdempotent = (deploymentId: string, error: Conflict) =>
10 observeDeployment(deploymentId).pipe(
11 Effect.flatMap((deployment) =>
12 deployment.status === "running" || deployment.status === "provisioning"
13 ? Effect.succeed(undefined)
14 : Effect.fail(error),
15 ),
16 Effect.catchTag("NotFound", () => Effect.fail(error)),
17 );
18
19const stopConflictIsIdempotent = (deploymentId: string, error: Conflict) =>
20 observeDeployment(deploymentId).pipe(
21 Effect.flatMap((deployment) =>
22 deployment.status === "stopped" || deployment.status === "stopping"
23 ? Effect.void
24 : Effect.fail(error),
25 ),
26 Effect.catchTag("NotFound", () => Effect.fail(error)),
27 );
28
29export const startDeploymentIdempotent = (deploymentId: string) =>
30 createDeploymentStart({ deploymentId }).pipe(
31 Effect.map((response) => response.data),
32 Effect.catchTag("Conflict", (error) =>
33 startConflictIsIdempotent(deploymentId, error),
34 ),
35 );
36
37export const stopDeploymentIdempotent = (deploymentId: string) =>
38 createDeploymentStop({ deploymentId }).pipe(
39 Effect.asVoid,
40 Effect.catchTag("Conflict", (error) =>
41 stopConflictIsIdempotent(deploymentId, error),
42 ),
43 );