npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

dauntless

v2.2.1

Published

Dauntless is a minimalist, error-tolerant, highly configurable http(s) request package for Node

Downloads

40

Readme

Durable HTTP/HTTPS Requests (version 2.x)

Dauntless is an error tolerant, flexible, and extensible HTTP/HTTPS request client for Node based off the XMLHttpRequest specification. Use Dauntless if your Node project requires:

  • Error tolerance for server backend issues via built-in exponential backoff
  • Implementation of native ES6 Promises and async-await
  • Hooks to easily check for request authorization
  • Flexible, extensible architecture with minimal assumptions about use cases
  • Small library size and only a single dependency
  • Browser and server support using the same HTTP request client

Dauntless assumes very little about what your request looks like or how you want to interact with it, preferring to give you the control of your requests.

Installation

It's as easy as installing the package via npm

npm install dauntless --save

Usage

Creating a promise-wrapped XHR request using Dauntless is as simple as sending a regular XHR request:

const dauntless = require('dauntless');
var client = new dauntless.client();
client.open(HttpMethod, requestUrl);
var promisedRequest = client.send(requestBody);

request-promise style invocation is also supported:

const dauntless = require('dauntless');
dauntless.rp(url, options);

See 'request-promise mode' below for more information.

Features

Though dauntless requires minimal configuration out of the box, client instances are highly configurable while still allowing you to focus on writing logic that powers your software.

Handlers, autoResolve, and autoReject

Dauntless uses callback functions (referred to as handlers) to deal with the three main states of the request: success, error, and retry. Handlers are functions with the following syntax:

function successHandler(res) {
// Do something with res, the response body passed into this function
}

Handlers are always invoked via .call, with the client as the 'this' context. When you pass no arguments into the client constructor, returnPromise, autoResolveRejectPromise, autoResolve, and autoReject default to true.

Implement custom resolution and/or rejection handling by setting client.autoResolve or client.autoReject to false and then calling setSuccessHandler (or setErrorHandler). You can then access the resolve and reject of the Promise returned by the client from within the successHandler and errorHandler callbacks by using this.resolve and this.reject.

Custom resolution and rejection is useful for situations where the response is paginated and you want to only resolve once you've paginated through all the results. Here's an example using the YouTube Data API:

function dataReader = (res) {
  // We're scoped to the Dauntless client here
  // Let's assume this follows the YouTube Data API's Channel Resource from Channels.list
  // first, parse res from JSON
  let response = JSON.parse(res);

  // Do what you need to do with dataReader

  if(response.nextPageToken) {
    // we've got more data...
    this.open(HttpMethod, requestUrlWithPageToken);
    if(this.returnPromise) this.returnPromise = false;
    this.send();
  } else {
    this.resolve();
  }
}

let client = new dauntless.client();
client.autoResolve = false;
client.setSuccessHandler(dataReader);
client.open(HttpMethod, requestUrl);
client.send();

Clean, concise code without having to go through callback hell.

Validation Handling

Every Dauntless client checks to make sure that the request is valid by way of the validationHandler. By default, that code looks like this:

    var validationHandler = function() { return this.url && this.method && this.xhr.status <= 1 };

Here's an example of a custom validationHandler implementation. It checks to see if an OAuth2 access token obtained through Google's OAuth2 flow has expired, refreshes if it has, and then returns true to say that we've got a valid token:

async function refreshToken() {
  if(!(this.url && this.method && this.xhr.status <= 1)) return false;
  if(tokenValidUntil <= Date.now()) {
      let refreshRequest = new dauntless.client();
      refreshRequest.open('POST', `https://www.googleapis.com/oauth2/v4/token?refresh_token=${refresh}&client_secret=${secret}&client_id=${id}&grant_type=refresh_token`);
      refreshRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      let response = await refreshRequest.send();
      let parsedResponse = JSON.parse(response);
    }
  return true;
}

var client = new dauntless.client();
client.open('GET', endpoint);
client.setValidationHandler(refreshToken);
client.send();

Now your client will automatically check to see if the access token is valid before proceeding with your initial request.

Response Code Ranges

By default, Dauntless requests consider HTTP 2xx and 3xx responses a "success" (successOn), 4xx responses an "error" (errorOn), and 5xx response a "retry" (retryOn). You can customize these ranges by using:

// Clears the range, then sets it to this inclusive range of values
client.setRange(beginning, end, client.successOn/errorOn/retryOn)

// Just adds the every number in the range to the range
client.addRange(beginning, end, client.successOn/errorOn/retryOn)

invokeXhr

Dauntless is based off the xmlhttprequest node module. You can access the underlying XMLHttpRequest object at any time by using

client.xhr.nameOfMethodOrProp

Alternatively, you can call methods and set properties of the XHR object in a batch by using invokeXhr. invokeXhr takes a hash where key names correspond to the XMLHttpRequest's properties. Values are either an array of arguments for a method, or a single value for a variable. For example:

const dauntless = require('dauntless');
let client = new dauntless.client(httpMethod, successHandler, failureHandler);
client.invokeXhr({ "setRequestHeader": ["headerName", "headerValue"]});

invokeXhr returns the object you pass as an argument, along with a returnValue to access any and all info captured by methods called via invokeXhr:

const dauntless = require('dauntless');
let client = new dauntless.client(httpMethod, successHandler, failureHandler);
var options = client.invokeXhr({ "getAllResponseHeaders"});
console.log(options.getAllResponseHeaders.returnValue);

request-promise mode

Dauntless requests can be invoked in a request-promise style configuration without losing access to features like exponential backoff.

const dauntless = require('dauntless');
dauntless.rp(url, options);

options has following structure:

options = {
  headers: { headerName1: headerValue1, headerName2: headerValue2, ... },
  validationHandler: <Function>,
  successHandler: <Function>,
  errorHandler: <Function>,
  autoResolve: Boolean,
  autoReject: Boolean,
  successOn: [ Array, of, integers, ... ],
  errorOn: [ Array, of, integers, ... ],
  retryOn: [ Array, of, integers, ... ],
  method: 'GET/POST/DELETE/etc',
  body: any valid request body
}