From 4592f51162bbb5e76d02920971d9a3d81190d08a Mon Sep 17 00:00:00 2001 From: Kevin Leung Date: Mon, 13 Jul 2026 23:00:06 +1000 Subject: [PATCH] Add AbortController and AbortSignal externs Add Node 24 AbortController/AbortSignal under js.node.web, including shared EventTarget path types so AbortSignal can extend EventTarget independently of the events PR. Co-authored-by: Cursor --- src/js/node/web/AbortController.hx | 46 +++++++++ src/js/node/web/AbortSignal.hx | 73 +++++++++++++ src/js/node/web/Event.hx | 161 +++++++++++++++++++++++++++++ src/js/node/web/EventTarget.hx | 107 +++++++++++++++++++ 4 files changed, 387 insertions(+) create mode 100644 src/js/node/web/AbortController.hx create mode 100644 src/js/node/web/AbortSignal.hx create mode 100644 src/js/node/web/Event.hx create mode 100644 src/js/node/web/EventTarget.hx diff --git a/src/js/node/web/AbortController.hx b/src/js/node/web/AbortController.hx new file mode 100644 index 00000000..9c40e249 --- /dev/null +++ b/src/js/node/web/AbortController.hx @@ -0,0 +1,46 @@ +/* + * Copyright (C)2014-2020 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package js.node.web; + +/** + A utility class used to signal cancelation in selected `Promise`-based APIs. + The API is based on the Web API `AbortController`. + + @see https://nodejs.org/api/globals.html#class-abortcontroller +**/ +@:native("AbortController") +extern class AbortController { + /** + The `AbortSignal` object associated with this controller. + **/ + var signal(default, null):AbortSignal; + + function new():Void; + + /** + Triggers the abort signal, causing `signal` to emit the `'abort'` event. + + @param reason An optional reason, retrievable on the `AbortSignal`'s `reason` property. + **/ + function abort(?reason:Dynamic):Void; +} diff --git a/src/js/node/web/AbortSignal.hx b/src/js/node/web/AbortSignal.hx new file mode 100644 index 00000000..f5ff08a4 --- /dev/null +++ b/src/js/node/web/AbortSignal.hx @@ -0,0 +1,73 @@ +/* + * Copyright (C)2014-2020 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package js.node.web; + +import haxe.Constraints.Function; + +/** + Used to notify observers when `AbortController.abort()` is called. + + Extends `js.node.web.EventTarget`. Prefer these Node web externs over the + incomplete Haxe standard library `js.html.AbortSignal`. + + @see https://nodejs.org/api/globals.html#class-abortsignal +**/ +@:native("AbortSignal") +extern class AbortSignal extends EventTarget { + /** + Returns a new already aborted `AbortSignal`. + **/ + static function abort(?reason:Dynamic):AbortSignal; + + /** + Returns a new `AbortSignal` which will be aborted in `delay` milliseconds. + **/ + static function timeout(delay:Float):AbortSignal; + + /** + Returns a new `AbortSignal` which will be aborted if any of the provided + signals are aborted. Its `reason` will be set to whichever signal caused the abort. + **/ + static function any(signals:Array):AbortSignal; + + /** + True after the associated `AbortController` has been aborted. + **/ + var aborted(default, null):Bool; + + /** + An optional reason specified when the `AbortSignal` was triggered. + **/ + var reason(default, null):Dynamic; + + /** + An optional callback function that may be set by user code to be notified + when `AbortController.abort()` has been called. + **/ + var onabort:Function; + + /** + If `aborted` is `true`, throws `reason`. + **/ + function throwIfAborted():Void; +} diff --git a/src/js/node/web/Event.hx b/src/js/node/web/Event.hx new file mode 100644 index 00000000..46fcd57d --- /dev/null +++ b/src/js/node/web/Event.hx @@ -0,0 +1,161 @@ +/* + * Copyright (C)2014-2020 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package js.node.web; + +/** + A browser-compatible implementation of the `Event` class. + + @see https://nodejs.org/api/events.html#class-event + @see https://nodejs.org/api/globals.html#class-event +**/ +@:native("Event") +extern class Event { + static inline var NONE:Int = 0; + static inline var CAPTURING_PHASE:Int = 1; + static inline var AT_TARGET:Int = 2; + static inline var BUBBLING_PHASE:Int = 3; + + /** + The event type identifier. + **/ + var type(default, null):String; + + /** + The `EventTarget` dispatching the event. + **/ + var target(default, null):EventTarget; + + /** + Alias for `target`. + **/ + var currentTarget(default, null):EventTarget; + + /** + Returns `0` while an event is not being dispatched, `2` while it is being dispatched. + This is not used in Node.js and is provided purely for completeness. + **/ + var eventPhase(default, null):Int; + + /** + Always returns `false` in Node.js. Provided purely for completeness. + **/ + var bubbles(default, null):Bool; + + /** + True if the event was created with the `cancelable` option. + **/ + var cancelable(default, null):Bool; + + /** + Stability: 3 - Legacy: Use `defaultPrevented` instead. + + True if the event has not been canceled. + **/ + var returnValue:Bool; + + /** + Is `true` if `cancelable` is `true` and `preventDefault()` has been called. + **/ + var defaultPrevented(default, null):Bool; + + /** + Always returns `false` in Node.js. Provided purely for completeness. + **/ + var composed(default, null):Bool; + + /** + The `"abort"` event is emitted with `isTrusted` set to `true`. + The value is `false` in all other cases. + **/ + var isTrusted(default, null):Bool; + + /** + The millisecond timestamp when the `Event` object was created. + **/ + var timeStamp(default, null):Float; + + /** + Stability: 3 - Legacy: Use `stopPropagation()` instead. + + Alias for `stopPropagation()` if set to `true`. + **/ + var cancelBubble:Bool; + + /** + Stability: 3 - Legacy: Use `target` instead. + + Alias for `target`. + **/ + var srcElement(default, null):EventTarget; + + function new(type:String, ?eventInitDict:EventInit):Void; + + /** + Returns an array containing the current `EventTarget` as the only entry, + or empty if the event is not being dispatched. + This is not used in Node.js and is provided purely for completeness. + **/ + function composedPath():Array; + + /** + Sets the `defaultPrevented` property to `true` if `cancelable` is `true`. + **/ + function preventDefault():Void; + + /** + Stops the invocation of event listeners after the current one completes. + **/ + function stopImmediatePropagation():Void; + + /** + This is not used in Node.js and is provided purely for completeness. + **/ + function stopPropagation():Void; + + /** + Stability: 3 - Legacy: The WHATWG spec considers it deprecated. + + Redundant with event constructors and incapable of setting `composed`. + **/ + function initEvent(type:String, ?bubbles:Bool, ?cancelable:Bool):Void; +} + +/** + Options passed to the `Event` constructor. +**/ +typedef EventInit = { + /** + Not used in Node.js. Default: `false`. + **/ + @:optional var bubbles:Bool; + + /** + When `true`, `preventDefault()` can cancel the event. Default: `false`. + **/ + @:optional var cancelable:Bool; + + /** + Not used in Node.js. Default: `false`. + **/ + @:optional var composed:Bool; +} diff --git a/src/js/node/web/EventTarget.hx b/src/js/node/web/EventTarget.hx new file mode 100644 index 00000000..17956383 --- /dev/null +++ b/src/js/node/web/EventTarget.hx @@ -0,0 +1,107 @@ +/* + * Copyright (C)2014-2020 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package js.node.web; + +import haxe.Constraints.Function; +import haxe.extern.EitherType; + +/** + A browser-compatible implementation of the `EventTarget` class. + + @see https://nodejs.org/api/events.html#class-eventtarget + @see https://nodejs.org/api/globals.html#class-eventtarget +**/ +@:native("EventTarget") +extern class EventTarget { + function new():Void; + + /** + Adds a new handler for the `type` event. + Any given `listener` is added only once per `type` and per `capture` option value. + **/ + @:overload(function(type:String, listener:EventListener, ?options:EitherType):Void {}) + function addEventListener(type:String, listener:Function, ?options:EitherType):Void; + + /** + Removes the `listener` from the list of handlers for event `type`. + **/ + @:overload(function(type:String, listener:EventListener, ?options:EitherType):Void {}) + function removeEventListener(type:String, listener:Function, ?options:EitherType):Void; + + /** + Dispatches the `event` to the list of handlers for `event.type`. + + @return `true` if either event's `cancelable` attribute value is false + or its `preventDefault()` method was not invoked, otherwise `false`. + **/ + function dispatchEvent(event:Event):Bool; +} + +/** + An object with a `handleEvent` method, usable as an event listener. +**/ +typedef EventListener = { + function handleEvent(event:Event):Void; +} + +/** + Options for `EventTarget.removeEventListener`. +**/ +typedef EventListenerOptions = { + /** + Not directly used by Node.js except as part of the listener registration key. + Default: `false`. + **/ + @:optional var capture:Bool; +} + +/** + Options for `EventTarget.addEventListener`. +**/ +typedef AddEventListenerOptions = { + /** + Not directly used by Node.js except as part of the listener registration key. + Default: `false`. + **/ + @:optional var capture:Bool; + + /** + When `true`, the listener is automatically removed when it is first invoked. + Default: `false`. + **/ + @:optional var once:Bool; + + /** + When `true`, serves as a hint that the listener will not call `preventDefault()`. + Default: `false`. + **/ + @:optional var passive:Bool; + + /** + The listener will be removed when the given `AbortSignal` object's `abort()` method is called. + + Typed as `Dynamic` so this module does not hard-depend on the AbortSignal externs; + use `js.node.web.AbortSignal` when that module is available. + **/ + @:optional var signal:Dynamic; +}