-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lib: refactor transferable AbortSignal #43388
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -1470,6 +1470,33 @@ Returns the `string` after replacing any surrogate code points | |||||||||
(or equivalently, any unpaired surrogate code units) with the | ||||||||||
Unicode "replacement character" U+FFFD. | ||||||||||
|
||||||||||
## `util.transferableAbortController()` | ||||||||||
|
||||||||||
<!-- | ||||||||||
added: REPLACEME | ||||||||||
--> | ||||||||||
|
||||||||||
Creates and returns an {AbortController} instance whose {AbortSignal} is marked | ||||||||||
as transferable and can be used with `structuredClone()` or `postMessage()`. | ||||||||||
|
||||||||||
## `util.transferableAbortSignal(signal)` | ||||||||||
|
||||||||||
<!-- | ||||||||||
added: REPLACEME | ||||||||||
--> | ||||||||||
|
||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
* `signal` {AbortSignal} | ||||||||||
* Returns: {AbortSignal} | ||||||||||
|
||||||||||
Marks the given {AbortSignal} as transferable so that it can be used with | ||||||||||
`structuredClone()` and `postMessage()`. | ||||||||||
|
||||||||||
```cjs | ||||||||||
const signal = transferableAbortSignal(AbortSignal.timeout(100)); | ||||||||||
const channel = new MessageChannel(); | ||||||||||
channel.port2.postMessage(signal, [signal]); | ||||||||||
``` | ||||||||||
|
||||||||||
## `util.types` | ||||||||||
|
||||||||||
<!-- YAML | ||||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -9,6 +9,7 @@ const { | |||||
ObjectSetPrototypeOf, | ||||||
ObjectDefineProperty, | ||||||
SafeFinalizationRegistry, | ||||||
ReflectConstruct, | ||||||
SafeSet, | ||||||
Symbol, | ||||||
SymbolToStringTag, | ||||||
|
@@ -31,6 +32,7 @@ const { inspect } = require('internal/util/inspect'); | |||||
const { | ||||||
codes: { | ||||||
ERR_ILLEGAL_CONSTRUCTOR, | ||||||
ERR_INVALID_ARG_TYPE, | ||||||
ERR_INVALID_THIS, | ||||||
} | ||||||
} = require('internal/errors'); | ||||||
|
@@ -159,7 +161,7 @@ class AbortSignal extends EventTarget { | |||||
*/ | ||||||
static abort( | ||||||
reason = new DOMException('This operation was aborted', 'AbortError')) { | ||||||
return createAbortSignal(true, reason); | ||||||
return createAbortSignal({ aborted: true, reason }); | ||||||
} | ||||||
|
||||||
/** | ||||||
|
@@ -256,7 +258,7 @@ class AbortSignal extends EventTarget { | |||||
} | ||||||
|
||||||
function ClonedAbortSignal() { | ||||||
return createAbortSignal(); | ||||||
return createAbortSignal({ transferable: true }); | ||||||
} | ||||||
ClonedAbortSignal.prototype[kDeserialize] = () => {}; | ||||||
|
||||||
|
@@ -274,12 +276,25 @@ ObjectDefineProperty(AbortSignal.prototype, SymbolToStringTag, { | |||||
|
||||||
defineEventHandler(AbortSignal.prototype, 'abort'); | ||||||
|
||||||
function createAbortSignal(aborted = false, reason = undefined) { | ||||||
/** | ||||||
* @param {{ | ||||||
* aborted? : boolean, | ||||||
* reason? : any, | ||||||
* transferable? : boolean | ||||||
* }} [init] | ||||||
* @returns {AbortSignal} | ||||||
*/ | ||||||
function createAbortSignal(init) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
and then requiring |
||||||
const { | ||||||
aborted = false, | ||||||
reason = undefined, | ||||||
transferable = false, | ||||||
} = init; | ||||||
const signal = new EventTarget(); | ||||||
ObjectSetPrototypeOf(signal, AbortSignal.prototype); | ||||||
signal[kAborted] = aborted; | ||||||
signal[kReason] = reason; | ||||||
return lazyMakeTransferable(signal); | ||||||
return transferable ? lazyMakeTransferable(signal) : signal; | ||||||
} | ||||||
|
||||||
function abortSignal(signal, reason) { | ||||||
|
@@ -329,6 +344,26 @@ class AbortController { | |||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
* Enables the AbortSignal to be transferable using structuredClone/postMessage. | ||||||
* @param {AbortSignal} signal | ||||||
* @returns {AbortSignal} | ||||||
*/ | ||||||
function transferableAbortSignal(signal) { | ||||||
if (signal?.[kAborted] === undefined) | ||||||
throw new ERR_INVALID_ARG_TYPE('signal', 'AbortSignal', signal); | ||||||
return makeTransferable(signal); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Creates an AbortController with a transferable AbortSignal | ||||||
*/ | ||||||
function transferableAbortController() { | ||||||
return ReflectConstruct(function() { | ||||||
this[kSignal] = createAbortSignal({ transferable: true }); | ||||||
}, [], AbortController); | ||||||
} | ||||||
|
||||||
ObjectDefineProperties(AbortController.prototype, { | ||||||
signal: kEnumerableProperty, | ||||||
abort: kEnumerableProperty, | ||||||
|
@@ -347,4 +382,6 @@ module.exports = { | |||||
AbortController, | ||||||
AbortSignal, | ||||||
ClonedAbortSignal, | ||||||
transferableAbortSignal, | ||||||
transferableAbortController, | ||||||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.