Git Product home page Git Product logo

abort-controller's People

Contributors

caub avatar frogthefrog avatar mysticatea avatar southpolesteve avatar timothygu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

abort-controller's Issues

TypeScript support is broken

Looks like after rewrite to TypeScript "types" key in package.json was lost, which is necessary for be useful in TypeScript.

Add a ponyfill export

Currently, the two ways of consuming this package have downsides:

  1. The abort-controller export relies on the native implementation in browsers, which will not work in older browsers
  2. The abort-controller/polyfill export patches the global AbortController if not present, which can be undesirable

It would be handy to support a ponyfill export which can offer the benefits of both.

(It's likely that this package is used in combination with cross-fetch, which encourages the use of its ponyfill export in its README.)

TypeScript error: "Type 'AbortSignal' is missing the following properties from type 'AbortSignal': reason, throwIfAborted"

Using latest version of all packages at time of writing:

package.json:

{
  "dependencies": {
    "@types/node": "^17.0.42",
    "abort-controller": "^3.0.0",
    "typescript": "^4.7.3"
  }
}

main.ts:

import AbortController from "abort-controller";

/*
Type 'typeof AbortController' is not assignable to type '{ new (): AbortController; prototype: AbortController; }'.
  The types of 'prototype.signal' are incompatible between these types.
    Type 'AbortSignal' is missing the following properties from type 'AbortSignal': reason, throwIfAborted
*/
globalThis.AbortController = AbortController;

We can fix it by using the global AbortController type:

diff --git a/node_modules/abort-controller/dist/abort-controller.d.ts b/node_modules/abort-controller/dist/abort-controller.d.ts
index 75852fb..aa25471 100644
--- a/node_modules/abort-controller/dist/abort-controller.d.ts
+++ b/node_modules/abort-controller/dist/abort-controller.d.ts
@@ -24,20 +24,6 @@ declare class AbortSignal extends EventTarget<Events, EventAttributes> {
  * The AbortController.
  * @see https://dom.spec.whatwg.org/#abortcontroller
  */
-declare class AbortController {
-    /**
-     * Initialize this controller.
-     */
-    constructor()
-    /**
-     * Returns the `AbortSignal` object associated with this object.
-     */
-    readonly signal: AbortSignal
-    /**
-     * Abort and signal to any observers that the associated activity is to be aborted.
-     */
-    abort(): void
-}
-
+declare const AbortController: typeof globalThis.AbortController;
 export default AbortController
 export { AbortController, AbortSignal }

Doesn't work

Browser native signal looks like this:

AbortSignal {aborted: false, onabort: null}

and it works. But, when I import your package and use the signal it generates, there is zero network traffic (fetch requests don't fire) and the signal is like this:

AbortSignal {}

Unable to timeout Promise.

So I had an idea to use Abort Controller to stop long running async operations (basically for awaited promises put timeout).
However it seems like it has no effect at all (same as pure NodeJS).

Idea behind this code is to abort long running awaited promises.

const AbortController = require('node-abort-controller');

async function init() {

  async function myLongRunningAsyncTask(timeToDone) {
    return new Promise(resolve => setTimeout(() => {
      console.log(`I got my long running task done in ${timeToDone}ms!`);
      resolve(true);
    }, timeToDone));
  }

  async function timeout(timeout, controller) {
    return new Promise( resolve => setTimeout( () => {
      console.log('Timeout signal');
      controller.abort();
      resolve('Timeout');
    }));
  }

  async function doSomethingAsync(promise, signal) {

    if (signal.aborted) {
      return Promise.reject('Timeout!');
    }

    return new Promise(  async (resolve, reject) => {
      signal.addEventListener('abort', () => {
        reject('Timeout!');
      });
      console.log('--- Promise Started ---');
      await promise;
      console.log('--- Promise Ended ---');
      resolve(promise);
    });
  }

  console.log('Start');
  const controller = new AbortController();
  const signal = controller.signal;
  try {
    await Promise.race([
      doSomethingAsync(
        myLongRunningAsyncTask(700), signal
      ),
      timeout(500, controller)
    ]);
  } catch (e) {
    console.log(e);
  }
  console.log('End');

}

init();

Sadly is has no effect....

Start
--- Promise Started ---
Timeout signal
Timeout!
End
I got my long running task done in 700ms!
--- Promise Ended ---

The perfection would be that long running async operation is killed when I call abort, however it seems like it is not possible?

Browser code missing named AbortController export

browser.js is missing the AbortController named export.
The AbortController named export exists in src/abort-controller.ts (and browser.mjs), however, is missing in browser.js.
This results in an inconsistency. Code that successfully runs in nodejs throws an unexpected error when run in the browser.
Ex:

import {AbortController} from "abort-controller';
...

Typescript public interface includes an exported AbortController member, and popular convention is to use a named export if available (See this eslint-plugin-export rule). Thus, this issue will very likely affect direct consumers of this library, and worse, consumers further downstream, if consumers don't explicitly have browser tests!

This issue is for documentation purposes as several PRs implementing a fix are already open.
See: #22 and #29

can't ever reset a signal once it's been aborted

the pattern i'm using here is a retry policy wrapped around a fetch request (using graphql-request).

i do not have the ability to re-define the fetch options every time i retry the request, as the fetch call is made internally in a dependency.

but i do have the ability to define the initial client.

inside the retry-handler, i planned on resetting the signal if timed out. but you can't currently do this as once a signal is aborted, it's aborted for good, and the map of aborted signals is module-private.

would you be open to exploring a reset API for these signals?

Browser support?

I can't find anywhere that documents what the browser support for this shim is.

How does it compare to the innate AbortController support? How much market share, if any, am I gaining by using this?

Update the event-target-shim dependency

The event-target-shim dependency is a major version out of date, resulting in duplicate installation headaches for projects that actually need the newer event-target-shim version to polyfill event related globals (the old version doesn't export the needed classes) at the same time as the abort-controller/polyfill.

For example, in graphql-react-examples:

npm ls event-target-shim
graphql-react-examples@ /[redacted]/graphql-react-examples
├─┬ [email protected]
│ └── [email protected]
└── [email protected]

https://github.com/jaydenseric/graphql-react-examples/blob/4b732478987ea452acfb43c752ab99512463d9b2/utils/nodePolyfills.js#L1-L22

if (typeof window === 'undefined') {
  if (!('performance' in global))
    global.performance = require('perf_hooks').performance;

  if (!('EventTarget' in global))
    global.EventTarget =
      require('events').EventTarget || require('event-target-shim').EventTarget;

  if (!('Event' in global))
    global.Event =
      require('events').Event || require('event-target-shim').Event;

  if (!('CustomEvent' in global))
    global.CustomEvent = class CustomEvent extends Event {
      constructor(eventName, { detail, ...eventOptions } = {}) {
        super(eventName, eventOptions);
        this.detail = detail;
      }
    };

  require('abort-controller/polyfill');
}

controller.signal.constructor.name is invalid?

See here https://jsfiddle.net/vitaly_zdanevich/4k1x8wbj/3/

const {AbortController} = window.AbortControllerShim

// Create an instance.
const controller = new AbortController()
console.log('name:', controller.signal.constructor.name)
const signal = controller.signal

// Register a listenr.
signal.addEventListener("abort", () => {
    console.log("aborted!")
})

// Abort.
controller.abort()

The output is name: d.

Why a? In my project I have a problem that controller.signal.constructor.name is AbortSignal2, I do not understand why. But in another tests AbortSignal...

TypeError: Class extends value undefined ... when importing

When I attempt to run tests with jest, Node throws:

TypeError: Class extends value undefined is not a constructor or null

> 1 | import { AbortController } from "abort-controller"
  2 | import { ToastStyles } from "react-native-toaster"

This still works in the run-time app.

I tried mocking it out in the test with

jest.mock("abort-controller")

but it doesn't make a difference.

ModuleNotFoundError on export

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Today I used patch-package to patch [email protected] for the project I'm working on.

I kept getting the rolling error when trying to export web in expo.

Failed to compile
ModuleNotFoundError: Module not found: Error: Can't resolve './dist/abort-controller' in 'node_modules/abort-controller'
Did you mean 'abort-controller.mjs'?
BREAKING CHANGE: The request './dist/abort-controller' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.

Node v16.17.1

Here is the diff that solved my problem:

diff --git a/node_modules/abort-controller/polyfill.mjs b/node_modules/abort-controller/polyfill.mjs
index 0602a64..cf581af 100644
--- a/node_modules/abort-controller/polyfill.mjs
+++ b/node_modules/abort-controller/polyfill.mjs
@@ -1,5 +1,5 @@
 /*globals self, window */
-import * as ac from "./dist/abort-controller"
+import * as ac from "./dist/abort-controller.mjs"
 
 /*eslint-disable @mysticatea/prettier */
 const g =

This issue body was partially generated by patch-package.

Abort fetches in react native

Hi, I have a little problem... probably I'm misleading different specs.
I read this article on how to abort a fetch request: https://developers.google.com/web/updates/2017/09/abortable-fetch

and I'm trying to do so in react-native with your library ('cause the standard AbortController has yet to arrive) but it doesn't abort anything.

This is my code:

const controller = new AbortController();
const signal = controller.signal;

setTimeout(() => controller.abort(), 5000);

fetch(url, { signal }).then(response => {
  return response.text();
}).then(text => {
  console.log(text);
});

umdOutro causes issues with webpack+babel

const umdOutro = `if (typeof module === "undefined" && typeof define === "undefined") {

The umdOutro snippet causes issues when the polyfill is passed to webpack+babel.
We could not find a clear reason in your git history for adding this snippet.

We are also unsure if this is an issue with our config, webpack or babel.

Do you have any guidance or is there a change you can make to the snippet to resolve this issue?

Expected :

"undefined" == typeof module && "undefined" == typeof define

Actual :

false && false

Our config :

https://github.com/mrhenry/core-web/blob/test-suite/packages/core-web-tests/webpack.config.js

Our temporary patch :

https://github.com/mrhenry/core-web/blob/test-suite/packages/core-web-generator/generate.js#L102

fails to minify

I added your package to my React app and now I'm unable to compile my production build because of the following error.

Failed to minify the code from this file: 

 	./node_modules/abort-controller/dist/abort-controller.mjs:20 

Please bundle as iife also.

I have an old project where I cannot do imports so a pollyfill in iife format would be great so that I can just load it as a global polyfill.
EDIT:
UMD works.. I close this.

Use native AbortController when possible.

This library uses browser field of package.json in order to avoid including a shim and uses own implementation otherwise. That however creates problems when used in Electron (main process) because there it loads a own implementation which native APIs like fetch reject with error like:

TypeError: Failed to execute 'fetch' on 'Window': member signal is not of type AbortSignal.

It would be nice if implementation still checked for presence of native AbortSignal just in case it exists.

TypeScript support plan

Hey

First, i want to thank you for this great project!
I want to use it in nodejs + typescript project, And i will be happy to contribute declarations.
But the code is very real written, and i think i can just refactor it to TS, and to export types as part of the build. If you will accept a PR for that :)

BTW, typescript 2.8.1 (or even earlier ) has types for AbortController in lib.dom.d.ts already
It can serve as a point of reference

Thanks again!
Bnaya

ES-check error

Am getting this error with v3.0.0:

ES-Check: there were 1 ES version matching errors.

          ES-Check Error:
          ----
          · erroring file: ./dist/static/vendor.4cd45c7aadabd101b1e0.js
          · error: SyntaxError: The keyword 'const' is reserved (30:92360)
          · see the printed err.stack below for context
          ----

The application used is universal, so will be run in the browser and in node - how to fix this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.