Simplifying Nested Generators in Effect for API Calls

I'm finding myself doing a lot of nesting of generators when I am trying to do call APIs based on results of other APIs, wondering if there is a more out of the box solution with Effect for this?

const page = yield* Effect.all(
      _page.map((r) => {
        return Effect.gen(function* () {
          if (r.fileIds && r.fileIds.length > 0) {
            const files = yield* Effect.all(
              r.fileIds!.map((f) => {
                return Effect.gen(function* () {
                  const file = yield* Effect.promise(() => ctx.db.get(f));
                  if (!file) {
                    return yield* new ConvexServerError({
                      message: "idk",
                    });
                  }

                  const { metadata, ...restFile } = file;

                  const fileURL = yield* Effect.promise(() =>
                    ctx.storage.getUrl(file.storageId),
                  );

                  if (metadata && restFile.type === "image") {
                   // ...
                    return {
                     // ...
                    };
                  }

                  return {
                    fileURL,
                    ...restFile,
                  };
                });
              }),
            );

            return Effect.succeed({
              ...r,
              files,
            });
          }
          return Effect.succeed(r);
        });
      }),
    );
Was this page helpful?