Skip to content

Commit

Permalink
🗑️ Deprecate non-function invocations of call()
Browse files Browse the repository at this point in the history
There were too many overloads of call that ended up throwing off the
typings. Specifically, there were difficulties in disambiguating
between: `() => T` as a callable and `() => Promise<T>`, because `T`
could be `Promise<T>`.

This deprecates every other call() aside from async functions and
operation functions (generator functions).
  • Loading branch information
cowboyd committed Dec 14, 2024
1 parent 43a692b commit e466b02
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 20 deletions.
44 changes: 25 additions & 19 deletions lib/call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,13 @@ export type Callable<T> =
| (() => T);

/**
* Pause the current operation, then runs a promise, async function, plain function,
* or operation within a new scope. The calling operation will be resumed (or errored)
* Pause the current operation, then run an async function, or operation function in a new scope. The calling operation will be resumed (or errored)
* once call is completed.
*
* `call()` is a uniform integration point for calling async functions,
* evaluating promises, generator functions, operations, and plain
* functions.
* and generator functions.
*
* It can be used to treat a promise as an operation:
*
* @example
* ```javascript
* let response = yield* call(fetch('https://google.com'));
* ```
*
* or an async function:
* It can be used to invoke an async function:
*
* @example
* ```typescript
Expand All @@ -70,13 +61,6 @@ export type Callable<T> =
* }); // => socket is destroyed before returning
* ```
*
* It can be used to run a plain function:
*
* @example
* ```javascript
* yield* call(() => "a string");
* ```
*
* Because `call()` runs within its own {@link Scope}, it can also be used to
* establish [error boundaries](https://frontside.com/effection/docs/errors).
*
Expand Down Expand Up @@ -110,9 +94,31 @@ export type Callable<T> =
*/
export function call<T>(callable: () => Operation<T>): Operation<T>;
export function call<T>(callable: () => Promise<T>): Operation<T>;

/**
* @deprecated Using call with simple functions will be removed in v4.
* To convert simple functions into operations, use @{link lift}.
*/
export function call<T>(callable: () => T): Operation<T>;

/**
* @deprecated calling bare promises, operations, and constants will
* be removed in v4, always pass a function to call()
*
* before: call(operation);
* after: call(() => operation);
*/
export function call<T>(callable: Operation<T>): Operation<T>;

/**
* @deprecated calling bare promises, operations, and constants will
* be removed in v4, always pass a function to call()
*
* before: call(promise);
* after: call(() => promise);
*/
export function call<T>(callable: Promise<T>): Operation<T>;

export function call<T>(callable: Callable<T>): Operation<T> {
return action(function* (resolve, reject) {
try {
Expand Down
7 changes: 6 additions & 1 deletion lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ export interface Subscription<T, R> {
* Unless a context value is defined for a particular scope, it will inherit
* its value from its parent scope.
*/
export interface Context<T> extends Operation<T> {
export interface Context<T> {
/**
* A unique identifier for this context.
*/
Expand All @@ -265,6 +265,11 @@ export interface Context<T> extends Operation<T> {
* set, and there is no default value, then this will return `undefined`.
*/
get(): Operation<T | undefined>;

/**
* @deprecated instead of using a bare context as an operation, use `Context.expect()` instead
*/
[Symbol.iterator]: Operation<T>[typeof Symbol.iterator];
}

/**
Expand Down

0 comments on commit e466b02

Please sign in to comment.