New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

use-http

Package Overview
Dependencies
Maintainers
1
Versions
102
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

use-http - npm Package Compare versions

Comparing version 0.3.7 to 0.3.8

dist/ErrorBoundary.d.ts

1

dist/types.d.ts

@@ -141,2 +141,3 @@ import { ReactNode } from 'react';

cacheLife?: number;
suspense?: boolean;
}

@@ -143,0 +144,0 @@ export declare type Options = CustomOptions & Omit<RequestInit, 'body'> & {

@@ -69,3 +69,3 @@ "use strict";

var initialURL = customOptions.url, path = customOptions.path, interceptors = customOptions.interceptors, timeout = customOptions.timeout, retries = customOptions.retries, onTimeout = customOptions.onTimeout, onAbort = customOptions.onAbort, onNewData = customOptions.onNewData, perPage = customOptions.perPage, cachePolicy = customOptions.cachePolicy, // 'cache-first' by default
cacheLife = customOptions.cacheLife;
cacheLife = customOptions.cacheLife, suspense = customOptions.suspense;
var isServer = use_ssr_1.default().isServer;

@@ -79,3 +79,6 @@ var controller = react_1.useRef();

var hasMore = react_1.useRef(true);
var suspenseStatus = react_1.useRef('pending');
var suspender = react_1.useRef();
var _b = react_1.useState(defaults.loading), loading = _b[0], setLoading = _b[1];
var forceUpdate = react_1.useReducer(function () { return ({}); }, [])[1];
var makeFetch = react_1.useCallback(function (method) {

@@ -95,4 +98,6 @@ var doFetch = function (routeOrBody, body) { return __awaiter(_this, void 0, void 0, function () {

_a = _c.sent(), url = _a.url, options = _a.options, response = _a.response;
if (!suspense)
setLoading(true);
error.current = undefined;
if (!(response.isCached && cachePolicy === CACHE_FIRST)) return [3 /*break*/, 5];
setLoading(true);
if (!response.isExpired) return [3 /*break*/, 2];

@@ -109,3 +114,4 @@ cache.delete(response.id);

data.current = res.current.data;
setLoading(false);
if (!suspense)
setLoading(false);
return [2 /*return*/, data.current];

@@ -121,4 +127,2 @@ case 4:

return [2 /*return*/, data.current];
setLoading(true);
error.current = undefined;
timer = timeout > 0 && setTimeout(function () {

@@ -172,9 +176,37 @@ timedout.current = true;

case 11:
setLoading(false);
if (!suspense)
setLoading(false);
return [2 /*return*/, data.current];
}
});
}); };
}); }; // end of doFetch()
if (suspense) {
return function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return __awaiter(_this, void 0, void 0, function () {
var newData;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
suspender.current = doFetch.apply(void 0, args).then(function (newData) {
suspenseStatus.current = 'success';
return newData;
}, function () {
suspenseStatus.current = 'error';
});
forceUpdate();
return [4 /*yield*/, suspender.current];
case 1:
newData = _a.sent();
return [2 /*return*/, newData];
}
});
});
};
}
return doFetch;
}, [isServer, onAbort, requestInit, initialURL, path, interceptors, cachePolicy, perPage, timeout, cacheLife, onTimeout, defaults.data, onNewData]);
}, [isServer, onAbort, requestInit, initialURL, path, interceptors, cachePolicy, perPage, timeout, cacheLife, onTimeout, defaults.data, onNewData, forceUpdate, suspense]);
var post = react_1.useCallback(makeFetch(types_1.HTTPMethod.POST), [makeFetch]);

@@ -211,3 +243,4 @@ var del = react_1.useCallback(makeFetch(types_1.HTTPMethod.DELETE), [makeFetch]);

value: function () {
var clonedResponse = ('clone' in res.current ? res.current.clone() : {});
var _a;
var clonedResponse = ('clone' in res.current ? res.current.clone() : (_a = {}, _a[field] = function () { console.error("You haven't made a http request yet"); }, _a));
return clonedResponse[field]();

@@ -222,3 +255,3 @@ },

react_1.useEffect(function () {
if (dependencies && Array.isArray(dependencies)) {
if (Array.isArray(dependencies)) {
var methodName = requestInit.method || types_1.HTTPMethod.GET;

@@ -237,3 +270,14 @@ var methodLower = methodName.toLowerCase();

react_1.useEffect(function () { return request.abort; }, []);
return Object.assign([request, response, loading, error.current], __assign({ request: request, response: response }, request));
var final = Object.assign([request, response, loading, error.current], __assign({ request: request, response: response }, request));
if (suspense && suspender.current) {
if (isServer)
throw new Error('Suspense on server side is not yet supported! 🙅‍♂️');
switch (suspenseStatus.current) {
case 'pending':
throw suspender.current;
case 'error':
throw error.current;
}
}
return final;
}

@@ -240,0 +284,0 @@ exports.useFetch = useFetch;

@@ -15,2 +15,3 @@ import { OptionsMaybeURL, NoUrlOptions, Flatten, CachePolicies, Interceptors, OverwriteGlobalOptions } from './types';

cacheLife: number;
suspense: boolean;
};

@@ -37,2 +38,3 @@ requestInit: RequestInit;

cacheLife: number;
suspense: boolean;
};

@@ -39,0 +41,0 @@ requestInit: {

7

dist/useFetchArgs.js

@@ -33,3 +33,4 @@ "use strict";

cachePolicy: types_1.CachePolicies.CACHE_FIRST,
cacheLife: 0
cacheLife: 0,
suspense: false
},

@@ -104,2 +105,3 @@ requestInit: { headers: {} },

var cacheLife = useField('cacheLife', urlOrOptions, optionsNoURLs);
var suspense = useField('suspense', urlOrOptions, optionsNoURLs);
var loading = react_1.useMemo(function () {

@@ -151,3 +153,4 @@ if (utils_1.isObject(urlOrOptions))

cachePolicy: cachePolicy,
cacheLife: cacheLife
cacheLife: cacheLife,
suspense: suspense
},

@@ -154,0 +157,0 @@ requestInit: requestInit,

{
"name": "use-http",
"version": "0.3.7",
"version": "0.3.8",
"homepage": "http://use-http.com",

@@ -19,3 +19,3 @@ "main": "dist/index.js",

"devDependencies": {
"@testing-library/react": "^9.2.0",
"@testing-library/react": "^10.0.0",
"@testing-library/react-hooks": "^3.0.0",

@@ -22,0 +22,0 @@ "@types/fetch-mock": "^7.2.3",

@@ -81,2 +81,3 @@ <a href="http://use-http.com">

- Built in caching
- Suspense<sup>(experimental)</sup> support

@@ -142,3 +143,3 @@ Usage

<details><summary><b>Basic Usage (no managed state) <code>useFetch</code></b></summary>
<details><summary><b>Basic Usage (auto managed state) <code>useFetch</code></b></summary>

@@ -171,4 +172,5 @@ This fetch is run `onMount/componentDidMount`. The last argument `[]` means it will run `onMount`. If you pass it a variable like `[someVariable]`, it will run `onMount` and again whenever `someVariable` changes values (aka `onUpdate`). **If no method is specified, GET is the default**

<details open><summary><b>Basic Usage (no managed state) with <code>Provider</code></b></summary>
<details open><summary><b>Basic Usage (auto managed state) with <code>Provider</code></b></summary>
```js

@@ -205,2 +207,80 @@ import useFetch, { Provider } from 'use-http'

<details open><summary><b>Suspense Mode (auto managed state)</b></summary>
```js
import useFetch, { Provider } from 'use-http'
function Todos() {
const { data: todos } = useFetch({
path: '/todos',
data: [],
suspense: true // can put it in 2 places. Here or in Provider
}, []) // onMount
return todos.map(todo => <div key={todo.id}>{todo.title}</div>)
}
function App() {
const options = {
suspense: true
}
return (
<Provider url='https://example.com' options={options}>
<Suspense fallback='Loading...'>
<Todos />
</Suspense>
</Provider>
)
}
```
[![Edit Basic Example](https://codesandbox.io/static/img/play-codesandbox.svg)]()
</details>
<details open><summary><b>Suspense Mode (managed state)</b></summary>
Can put `suspense` in 2 places. Either `useFetch` (A) or `Provider` (B).
```js
import useFetch, { Provider } from 'use-http'
function Todos() {
const [todos, setTodos] = useState([])
// A. can put `suspense: true` here
const { get, response } = useFetch({ data: [], suspense: true })
const loadInitialTodos = async () => {
const todos = await get('/todos')
if (response.ok) setTodos(todos)
}
const mounted = useRef(false)
useEffect(() => {
if (mounted.current) return
mounted.current = true
loadInitialTodos()
}, [])
return todos.map(todo => <div key={todo.id}>{todo.title}</div>)
}
function App() {
const options = {
suspense: true // B. can put `suspense: true` here too
}
return (
<Provider url='https://example.com' options={options}>
<Suspense fallback='Loading...'>
<Todos />
</Suspense>
</Provider>
)
}
```
[![Edit Basic Example](https://codesandbox.io/static/img/play-codesandbox.svg)]()
</details>
<div align="center">

@@ -273,5 +353,5 @@ <br>

<details open><summary><b>Destructured <code>useFetch</code></b></summary>
⚠️ The `response` object cannot be destructured! (at least not currently) ️️⚠️
⚠️ Do not destructure the `response` object! Technically you can do it, but if you need to access the `response.ok` from, for example, within a component's onClick handler, it will be a stale value for `ok` where it will be correct for `response.ok`. ️️⚠️
```js

@@ -283,5 +363,3 @@ var [request, response, loading, error] = useFetch('https://example.com')

request,
// the `response` is everything you would expect to be in a normal response from an http request with the `data` field added.
// ⚠️ The `response` object cannot be destructured! (at least not currently) ️️⚠️
response,
response, // 🚨 Do not destructure the `response` object!
loading,

@@ -294,10 +372,32 @@ error,

patch,
delete // don't destructure `delete` though, it's a keyword
del, // <- that's why we have this (del). or use `request.delete`
mutate, // GraphQL
query, // GraphQL
delete // don't destructure `delete` though, it's a keyword
del, // <- that's why we have this (del). or use `request.delete`
mutate, // GraphQL
query, // GraphQL
abort
} = useFetch('https://example.com')
// 🚨 Do not destructure the `response` object!
// 🚨 This just shows what fields are available in it.
var {
ok,
status,
headers,
data,
type,
statusText,
url,
body,
bodyUsed,
redirected,
// methods
json,
text,
formData,
blob,
arrayBuffer,
clone
} = response
var {
loading,

@@ -685,2 +785,3 @@ error,

| --------------------- | --------------------------------------------------------------------------|------------- |
| `suspense` | Enables React Suspense mode. [example]() | false |
| `cachePolicy` | These will be the same ones as Apollo's [fetch policies](https://www.apollographql.com/docs/react/api/react-apollo/#optionsfetchpolicy). Possible values are `cache-and-network`, `network-only`, `cache-only`, `no-cache`, `cache-first`. Currently only supports **`cache-first`** or **`no-cache`** | `cache-first` |

@@ -704,2 +805,5 @@ | `cacheLife` | After a successful cache update, that cache data will become stale after this duration | `0` |

// enables React Suspense mode
suspense: true, // defaults to `false`
// Cache responses to improve speed and reduce amount of requests

@@ -783,2 +887,8 @@ // Only one request to the same endpoint will be initiated unless cacheLife expires for 'cache-first'.

- [ ] suspense
- [ ] triggering it from outside the `<Suspense />` component.
- add `.read()` to `request`
- or make it work with just the `suspense: true` option
- both of these options need to be thought out a lot more^
- [ ] tests for this^ (triggering outside)
- [ ] maybe add translations [like this one](https://github.com/jamiebuilds/unstated-next)

@@ -788,2 +898,4 @@ - [ ] add browser support to docs [1](https://github.com/godban/browsers-support-badges) [2](https://gist.github.com/danbovey/b468c2f810ae8efe09cb5a6fac3eaee5) (currently does not support ie 11)

- [ ] add sponsors [similar to this](https://github.com/carbon-app/carbon)
- [ ] Error handling
- [ ] if calling `response.json()` and there is no response yet
- [ ] tests

@@ -799,5 +911,3 @@ - [ ] doFetchArgs tests for `response.isExpired`

- [ ] make this a github package
- [ ] Make work with React Suspense [current example WIP](https://codesandbox.io/s/7ww5950no0)
- [ ] get it all working on a SSR codesandbox, this way we can have api to call locally
- [ ] make GraphQL work with React Suspense
- [ ] make GraphQL examples in codesandbox

@@ -838,4 +948,2 @@ - [ ] Documentation:

const request = useFetch({
// enabled React Suspense mode
suspense: false,
// allows caching to persist after page refresh

@@ -850,6 +958,12 @@ persist: true, // false by default

cache: new Map(),
interceptors: {
// I think it's more scalable/clean to have this as an object.
// What if we only need the `route` and `options`?
request: async ({ options, url, path, route }) => {},
response: ({ response }) => {}
},
// can retry on certain http status codes
retryOn: [503],
// OR
retryOn(attempt, error, response) {
retryOn({ attempt, error, response }) {
// retry on any network error, or 4xx or 5xx status codes

@@ -862,3 +976,3 @@ if (error !== null || response.status >= 400) {

// This function receives a retryAttempt integer and returns the delay to apply before the next attempt in milliseconds
retryDelay(attempt, error, response) {
retryDelay({ attempt, error, response }) {
// applies exponential backoff

@@ -907,29 +1021,2 @@ return Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 30 * 1000)

<details><summary><b>The Goal With Suspense <sup><strong>(not implemented yet)</strong></sup></b></summary>
```jsx
import React, { Suspense, unstable_ConcurrentMode as ConcurrentMode, useEffect } from 'react'
function WithSuspense() {
const suspense = useFetch('https://example.com')
useEffect(() => {
suspense.read()
}, [])
if (!suspense.data) return null
return <pre>{suspense.data}</pre>
}
function App() (
<ConcurrentMode>
<Suspense fallback="Loading...">
<WithSuspense />
</Suspense>
</ConcurrentMode>
)
```
</details>
<details><summary><b>GraphQL with Suspense <sup><strong>(not implemented yet)</strong></sup></b></summary>

@@ -936,0 +1023,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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