1import { Query } from "@distilled.cloud/core/query";
2import { Railway } from "@distilled.cloud/railway";
3import * as Effect from "effect/Effect";
4import * as Schedule from "effect/Schedule";
5
6const isGoneInstance = (instance: {
7 deletedAt: string | null;
8 isPendingDeletion: boolean;
9 state: string | null;
10}) =>
11 instance.deletedAt != null ||
12 instance.isPendingDeletion ||
13 instance.state === "DELETED" ||
14 instance.state === "DELETING";
15
16const readVolumeInstance = Query.fn((id: string) => {
17 const instance = Railway.volumeInstance({ id });
18 return {
19 deletedAt: instance.deletedAt,
20 isPendingDeletion: instance.isPendingDeletion,
21 state: instance.state,
22 };
23});
24
25/** Poll `volumeInstance({id})` until Railway reports the instance gone. */
26export const waitUntilVolumeGone = (volumeInstanceId: string) =>
27 readVolumeInstance(volumeInstanceId).pipe(
28 Effect.map((instance) =>
29 isGoneInstance(instance) ? ("gone" as const) : ("found" as const),
30 ),
31 Effect.catchTag("RailwayNotFound", () => Effect.succeed("gone" as const)),
32 Effect.repeat({
33 schedule: Schedule.spaced("1 second"),
34 until: (status) => status === "gone",
35 times: 10,
36 }),
37 );