1import * as Effect from "effect/Effect";
2import * as Result from "effect/Result";
3
4/**
5 * Publishes every platform package at once, then the launcher, which must
6 * never be installable before the executables it points to. When one platform
7 * fails, the other uploads still finish rather than being interrupted: npm
8 * never accepts the same version twice, and an interrupted upload may already
9 * be live. The launcher is then skipped and the first failure is returned.
10 */
11export const publishPlatformsThenLauncher = <E, R>(input: {
12 readonly platformTarballs: ReadonlyArray<string>;
13 readonly launcherTarball: string;
14 readonly publish: (tarball: string) => Effect.Effect<void, E, R>;
15}) =>
16 Effect.gen(function* () {
17 const results = yield* Effect.all(input.platformTarballs.map(input.publish), {
18 concurrency: "unbounded",
19 mode: "result",
20 });
21 const failed = results.find(Result.isFailure);
22 if (failed) {
23 return yield* Effect.fail(failed.failure);
24 }
25 yield* input.publish(input.launcherTarball);
26 });