Skip to content

feat(async/unstable): allow AbortableOptions with optional signal in abortable#6971

Merged
kt3k merged 2 commits intodenoland:mainfrom
lowlighter:feat-abortable-options
Feb 20, 2026
Merged

feat(async/unstable): allow AbortableOptions with optional signal in abortable#6971
kt3k merged 2 commits intodenoland:mainfrom
lowlighter:feat-abortable-options

Conversation

@lowlighter
Copy link
Contributor

Close #6970

Make it so the abortable() can be called with both of these manners:

await abortable(promise, signal)
await abortable(promise, { signal })

The second one which is introduced, is close to the options object already supported by deadline/delay, making it easier for libraries developpers to reuse the same object by unifying these differents APIs, and also avoiding the burden of checking whether their promise must be wrapped by abortable or not depending on whether the signal is provided or not

async function foo(options: { signal?: AbortSignal } = {}) {
  await delay(100, options)
  await abortable(promise, options)
  await deadline(another_promise, options)
}

@lowlighter lowlighter requested a review from kt3k as a code owner January 25, 2026 20:09
@github-actions github-actions bot added the async label Jan 25, 2026
@codecov
Copy link

codecov bot commented Jan 25, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.20%. Comparing base (4d438dc) to head (8f0f43f).
⚠️ Report is 31 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6971      +/-   ##
==========================================
+ Coverage   94.19%   94.20%   +0.01%     
==========================================
  Files         600      601       +1     
  Lines       43290    43343      +53     
  Branches     6961     6973      +12     
==========================================
+ Hits        40776    40831      +55     
+ Misses       2459     2458       -1     
+ Partials       55       54       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@kt3k
Copy link
Member

kt3k commented Feb 16, 2026

I feel this overload isn't aligned with our style guide for the function signature https://docs.deno.com/runtime/contributing/style_guide/#exported-functions%3A-max-2-args%2C-put-the-rest-into-an-options-object

(I don't think there's a prior example of an argument which is optional in 2 different ways in std)

Also the ergonomic issue this PR tries to solve feels like too niche to me..

What do people think?

@tomas-zijdemans
Copy link
Contributor

tomas-zijdemans commented Feb 16, 2026

Agree with @kt3k . I vote for the simpler RetryOptions which is consistent with delay, deadline, waitFor and (hopefully) soon retry #6968

@kt3k
Copy link
Member

kt3k commented Feb 16, 2026

The situation is a bit tricky here. It already has the signatures of:

export function abortable<T>(p: Promise<T>, signal: AbortSignal): Promise<T>;
export function abortable<T>(p: AsyncIterable<T>, signal: AbortSignal): AsyncGenerator<T>;

(The signal is not optional here because abortable only makes sense with abort signal)

and because it's already a stable API, we can't remove positional signal argument.

@lowlighter
Copy link
Contributor Author

Yeah the main issue is that the abortable API is already stable, so that's why I suggested to support both signatures to be retro compatible

In my opinion the options object should have been the stabilised api, because as @tomas-zijdemans noted, almost all the other apis of the async package use a signal-compatible and are all in line except for abortable. I was personally confused at first myself why it wasn't possible to pass the same option object because of the same reason

But doing so makes it a breaking change so idk :/

@tomas-zijdemans
Copy link
Contributor

tomas-zijdemans commented Feb 16, 2026

If there's no appetite for a breaking change + a new major version, it's probably best to leave it as is (Abortable is a bit different since signal is required here, but an optional feature for retry and the others)

@kt3k
Copy link
Member

kt3k commented Feb 20, 2026

Maybe this is good for the consistency with other APIs, and improves the ergonomics. And because we can't make a breaking change for now, this would probably be the best we can do for it.

Copy link
Member

@kt3k kt3k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kt3k kt3k merged commit 0548e54 into denoland:main Feb 20, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider allowing signal with abortable optional and a no-op

3 participants