thefrontside / effection

Structured concurrency and effects for JavaScript

Home Page:https://frontside.com/effection

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Beefed up `call()` function.

cowboyd opened this issue · comments

Right now there are a lot of different ways to convert values into operations. There is expect() (Promise->Operation), call()(Operation->Operation), and op (Function -> Operation>.

starfx unifies all of these concepts into a single operation Should we bring this into Effection core?

I'm thinking the following variations should all work?:

// promise
call(Promise.resolve("hello"));
call(async () => "hello");

// values
call("hello");
call(() => "hello");

// Operation
call({ *[Symbol.iterator]() { return "hello" } } );
call(function*() { return "hello" });

Then we could deprecate expect() and op

This is one area that I feel pretty confident saying: users are not going to want to think about converting their promises into operations everytime they want to activate one inside a DC. It's not that much of a lift to support officially and the ergonomics make a ton of sense.

The bigger issue for me is supporting both safe and unsafe call() functionality. I built a safe() function that is the same as call() but wraps the call inside a Result type. This is extremely useful for cases where a user wants to run parallel operations and collect the results (e.g. starfx parallel).

It works but integrating both into a single API seems better.

This is one area that I feel pretty confident saying: users are not going to want to think about converting their promises into operations everytime they want to activate one inside a DC. It's not that much of a lift to support officially and the ergonomics make a ton of sense.

I agree, and our test cases we actually do this https://github.com/thefrontside/effection/blob/v3/test/suite.ts#L7-L16 However, I am very nervous about monkey-patching the global Promise prototype.

Is opt-in going to be still too awkward? Maybe we make it opt-out?

It works but integrating both into a single API seems better.

How would we integrate this into a single call() API since the type of the return value is of a different for safe calls?

However, I am very nervous about monkey-patching the global Promise prototype.

Why do we need to monkey-patch? starfx has call() that supports promises oob. What about that don't you like?

Oh, I thought you were saying we should be able to yield to promises

yield* someAsyncFunction();

vs

yield* call(someAsyncFunction());