Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fetch-dedupe

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fetch-dedupe - npm Package Compare versions

Comparing version 1.0.0 to 2.0.0

11

CHANGELOG.md
# Changelog
### v2.0.0 (2018/2/4)
**Breaking**
* `dedupeOptions` is now optional. The `responseType` is `"json"` by default, unless the
status code is 204, in which case it will be `"text"`.
### v1.0.0 (2018/2/4)

@@ -7,4 +14,4 @@

- `init` is now optional
- A `requestKey` will be generated for you if it is omitted
* `init` is now optional
* A `requestKey` will be generated for you if it is omitted

@@ -11,0 +18,0 @@ ### v0.1.0 (2018/2/4)

16

dist/fetch-dedupe.js

@@ -68,3 +68,4 @@ (function (global, factory) {

} else {
throw new Error('dedupeOptions are required.');
opts = {};
initToUse = {};
}

@@ -87,4 +88,3 @@

method: initToUse.method || input.method || '',
body: initToUse.body || input.body || '',
responseType: responseType
body: initToUse.body || input.body || ''
});

@@ -114,6 +114,14 @@

var request = fetch(input, initToUse).then(function (res) {
var responseTypeToUse = void 0;
if (responseType) {
responseTypeToUse = responseType;
} else if (res.status === 204) {
responseTypeToUse = 'text';
} else {
responseTypeToUse = 'json';
}
// The response body is a ReadableStream. ReadableStreams can only be read a single
// time, so we must handle that in a central location, here, before resolving
// the fetch.
return res[responseType]().then(function (data) {
return res[responseTypeToUse]().then(function (data) {
res.data = data;

@@ -120,0 +128,0 @@

@@ -1,1 +0,1 @@

!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r(e.FetchDedupe={})}(this,function(e){"use strict";var r={};function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=e.url,t=e.method,o=e.responseType,n=void 0===o?"":o,i=e.body,u=void 0===i?"":i;return[void 0===r?"":r,(void 0===t?"":t).toUpperCase(),n,u].join("||")}function o(e){var t=e.requestKey,o=e.res,n=e.err;(r[t]||[]).forEach(function(e){o?e.resolve(o):e.reject(n)}),r[t]=null}e.getRequestKey=t,e.isRequestInFlight=function(e){return!!r[e]},e.clearRequestCache=function(){r={}},e.fetchDedupe=function(e,n,i){var u=void 0,d=void 0;if(i)u=i,d=n;else{if(!n||!n.responseType)throw Error("dedupeOptions are required.");u=n,d={}}var s=u.responseType,f=void 0===s?"":s,c=u.dedupe,p=void 0===c||c,v=u.requestKey||t({url:e.url||e,method:d.method||e.method||"",body:d.body||e.body||"",responseType:f}),h=void 0;if(p){r[v]||(r[v]=[]);var y=r[v],a=!!y.length,l={};if(h=new Promise(function(e,r){l.resolve=e,l.reject=r}),y.push(l),a)return h}var m=fetch(e,d).then(function(e){return e[f]().then(function(r){if(e.data=r,!p)return e;o({requestKey:v,res:e})})},function(e){if(!p)return Promise.reject(e);o({requestKey:v,err:e})});return p?h:m},Object.defineProperty(e,"__esModule",{value:!0})});
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.FetchDedupe={})}(this,function(e){"use strict";var t={};function r(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.url,r=e.method,o=e.responseType,n=void 0===o?"":o,u=e.body,i=void 0===u?"":u;return[void 0===t?"":t,(void 0===r?"":r).toUpperCase(),n,i].join("||")}function o(e){var r=e.requestKey,o=e.res,n=e.err;(t[r]||[]).forEach(function(e){o?e.resolve(o):e.reject(n)}),t[r]=null}e.getRequestKey=r,e.isRequestInFlight=function(e){return!!t[e]},e.clearRequestCache=function(){t={}},e.fetchDedupe=function(e,n,u){var i=void 0,d=void 0;u?(i=u,d=n):n&&n.responseType?(i=n,d={}):(i={},d={});var s=i.responseType,f=void 0===s?"":s,c=i.dedupe,v=void 0===c||c,p=i.requestKey||r({url:e.url||e,method:d.method||e.method||"",body:d.body||e.body||""}),a=void 0;if(v){t[p]||(t[p]=[]);var h=t[p],y=!!h.length,l={};if(a=new Promise(function(e,t){l.resolve=e,l.reject=t}),h.push(l),y)return a}var m=fetch(e,d).then(function(e){return e[f||(204===e.status?"text":"json")]().then(function(t){if(e.data=t,!v)return e;o({requestKey:p,res:e})})},function(e){if(!v)return Promise.reject(e);o({requestKey:p,err:e})});return v?a:m},Object.defineProperty(e,"__esModule",{value:!0})});

@@ -62,3 +62,4 @@ // This is a cache of in-flight requests. Each request key maps to an

} else {
throw new Error('dedupeOptions are required.');
opts = {};
initToUse = {};
}

@@ -81,4 +82,3 @@

method: initToUse.method || input.method || '',
body: initToUse.body || input.body || '',
responseType: responseType
body: initToUse.body || input.body || ''
});

@@ -108,6 +108,14 @@

var request = fetch(input, initToUse).then(function (res) {
var responseTypeToUse = void 0;
if (responseType) {
responseTypeToUse = responseType;
} else if (res.status === 204) {
responseTypeToUse = 'text';
} else {
responseTypeToUse = 'json';
}
// The response body is a ReadableStream. ReadableStreams can only be read a single
// time, so we must handle that in a central location, here, before resolving
// the fetch.
return res[responseType]().then(function (data) {
return res[responseTypeToUse]().then(function (data) {
res.data = data;

@@ -114,0 +122,0 @@

@@ -59,3 +59,4 @@ 'use strict';

} else {
throw new Error('dedupeOptions are required.');
opts = {};
initToUse = {};
}

@@ -72,4 +73,3 @@

method: initToUse.method || input.method || '',
body: initToUse.body || input.body || '',
responseType: responseType
body: initToUse.body || input.body || ''
});

@@ -99,6 +99,14 @@

const request = fetch(input, initToUse).then(res => {
let responseTypeToUse;
if (responseType) {
responseTypeToUse = responseType;
} else if (res.status === 204) {
responseTypeToUse = 'text';
} else {
responseTypeToUse = 'json';
}
// The response body is a ReadableStream. ReadableStreams can only be read a single
// time, so we must handle that in a central location, here, before resolving
// the fetch.
return res[responseType]().then(data => {
return res[responseTypeToUse]().then(data => {
res.data = data;

@@ -105,0 +113,0 @@

{
"name": "fetch-dedupe",
"version": "1.0.0",
"version": "2.0.0",
"description": "A thin wrapper around fetch that prevents duplicate requests.",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -9,3 +9,3 @@ # Fetch Dedupe

A (very) thin wrapper around
[`global.fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
[`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
that prevents duplicate requests.

@@ -38,5 +38,5 @@

```js
import { getRequestKey, fetchDedupe } from 'fetch-dedupe';
import { fetchDedupe } from 'fetch-dedupe';
const url = '/test/2';
const fetchOptions = {
method: 'PATCH',

@@ -49,3 +49,3 @@ body: JSON.stringify({ a: 12 })

// third argument
fetchDedupe(url, fetchOptions, {responseType: 'json'}).then(res => {
fetchDedupe('/test/2', fetchOptions).then(res => {
console.log('Got some data', res.data);

@@ -55,3 +55,3 @@ });

// Additional requests are deduped. Nifty.
fetchDedupe(url, fetchOptions, {responseType: 'json'}).then(res => {
fetchDedupe('/test/2', fetchOptions).then(res => {
console.log('Got some data', res.data);

@@ -74,3 +74,3 @@ });

// The same code using `fetchDedupe`:
fetchDedupe(url, init, dedupeOptions)
fetchDedupe(url, init)
.then(res =>

@@ -81,3 +81,3 @@ console.log('got some cool data', res.data)

// Don't do this! It will throw an error.
fetchDedupe(url, init, dedupeOptions)
fetchDedupe(url, init)
.then(res => res.json())

@@ -96,3 +96,3 @@ .then(data => console.log('got some cool data', data));

##### `fetchDedupe( input [, init], dedupeOptions )`
##### `fetchDedupe( input [, init] [, dedupeOptions] )`

@@ -106,8 +106,10 @@ A wrapper around `global.fetch()`. The first two arguments are the same ones that you're used to.

The third option is `dedupeOptions`. This is an object with three attributes:
The third option is `dedupeOptions`, and it is also optional. This is an object with three attributes:
* `responseType`: Any of the methods from [the Body mixin](https://developer.mozilla.org/en-US/docs/Web/API/Body).
Typically, you will want to use `json`. Required.
The default is `"json"`, unless the response status code is `"204"`, in which case `"text"` will be used to prevent
an error.
* `requestKey`: A string that is used to determine if two requests are identical. You may pass this
to configure how the request key is generated. Optional.
to configure how the request key is generated. A default key will be generated for you if this is
omitted.
* `dedupe`: Whether or not to dedupe the request. Pass `false` and it will be as if this library

@@ -122,2 +124,10 @@ was not even being used. Defaults to `true`.

// Omitting everything except for the URL
fetchDedupe('/test/2');
// Just a URL and some init option
fetchDedupe('/test/2', {
method: 'DELETE'
});
// Omitting `init` and using a URL string as `input`

@@ -210,3 +220,3 @@ fetchDedupe('/test/2', {responseType: 'json'});

##### An empty response is throwing an error, what gives?
##### An empty response body is throwing an error, what gives?

@@ -221,9 +231,15 @@ Empty text strings are not valid JSON.

Consequently, using `json` as the `responseType` when a response's body is empty will cause an
Error to be thrown. To avoid this, we recommend using `text` instead.
Error to be thrown. To avoid this, we recommend using `text` in these situations instead.
APIs generally use empty bodies in conjunction with a 204 status code for responses
of "write" requests (deletes, updates, and less commonly creates).
of "write" requests (deletes, updates, and less commonly creates). For this reason, the default
behavior of `responseType` is `"json"` except in situations when a 204 code is returned, in which
case `"text"` will be used instead.
##### Why is `responseType` required?
If your API returns empty bodies with other codes, then you will need to manage that in your
application. As a "worst-case scenario," you can always pass `"text"` and then try/catch a
`JSON.parse` within a `.then()`.
##### Why is `responseType` even an option?
The argument that is returned to you in the `.then` callback of a call to `fetch()` is a

@@ -253,2 +269,2 @@ [Response object](https://developer.mozilla.org/en-US/docs/Web/API/Response). The body of a Response

[Apollo](https://www.apollographql.com/) inspired me to write this library.
[Apollo](https://www.apollographql.com/) inspired me to write this library.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc