Skip to content

Commit

Permalink
feat: Move /hooks package into /react pkg
Browse files Browse the repository at this point in the history
  • Loading branch information
ntucker committed Jun 20, 2024
1 parent abd9e14 commit 0e6b6b5
Show file tree
Hide file tree
Showing 29 changed files with 705 additions and 59 deletions.
7 changes: 7 additions & 0 deletions .changeset/modern-pears-burn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@data-client/react': patch
---

Add [useLoading()](https://dataclient.io/docs/api/useLoading), [useDebounce()](https://dataclient.io/docs/api/useDebounce), [useCancelling()](https://dataclient.io/docs/api/useCancelling)

These are taken from the hooks package.
7 changes: 7 additions & 0 deletions .changeset/poor-cherries-promise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@data-client/hooks': minor
---

**This repository has been deprecated and is no longer actively maintained.**

All hooks moved to [@data-client/react](https://www.npmjs.com/package/@data-client/react)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ For [REST](https://dataclient.io/rest), [GraphQL](https://dataclient.io/graphql)
## Installation

```bash
npm install --save @data-client/react @data-client/rest @data-client/test @data-client/hooks
npm install --save @data-client/react @data-client/rest @data-client/test
```

For more details, see [the Installation docs page](https://dataclient.io/docs/getting-started/installation).
Expand Down
4 changes: 1 addition & 3 deletions docs/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,7 @@ function ArticleEdit() {
[useLoading()](./api/useLoading.md) enhances async functions by tracking their loading and error states.

```tsx
import { useController } from '@data-client/react';
import { useLoading } from '@data-client/hooks';
import { useController, useLoading } from '@data-client/react';

function ArticleEdit() {
const ctrl = useController();
Expand All @@ -279,7 +278,6 @@ React 18 version with [useTransition](https://react.dev/reference/react/useTrans
```tsx
import { useTransition } from 'react';
import { useController } from '@data-client/react';
import { useLoading } from '@data-client/hooks';

function ArticleEdit() {
const ctrl = useController();
Expand Down
2 changes: 1 addition & 1 deletion docs/core/api/useCache.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const UserResource = createResource({
```

```tsx title="Unauthed" collapsed
import { useLoading } from '@data-client/hooks';
import { useLoading } from '@data-client/react';
import { UserResource } from './UserResource';

export default function Unauthed() {
Expand Down
4 changes: 0 additions & 4 deletions docs/core/api/useCancelling.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ Builds an Endpoint that cancels fetch everytime parameters change

## Usage

<PkgInstall pkgs="@data-client/hooks" />

<UseCancelling />

:::warning Warning
Expand All @@ -37,5 +35,3 @@ function useCancelling<
},
>(endpoint: E, ...args: readonly [...Parameters<E>] | readonly [null]): E {
```
Part of [@data-client/hooks](https://www.npmjs.com/package/@data-client/hooks)
7 changes: 1 addition & 6 deletions docs/core/api/useDebounce.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ Useful to avoid spamming network requests when parameters might change quickly (

## Usage

<PkgInstall pkgs="@data-client/hooks" />

<HooksPlayground row>

```ts title="IssueQuery" collapsed
Expand Down Expand Up @@ -84,8 +82,7 @@ export default React.memo(IssueList) as typeof IssueList;
```

```tsx title="SearchIssues" {8}
import { useDebounce } from '@data-client/hooks';
import { AsyncBoundary } from '@data-client/react';
import { useDebounce, AsyncBoundary } from '@data-client/react';
import IssueList from './IssueList';

export default function SearchIssues() {
Expand Down Expand Up @@ -118,5 +115,3 @@ function useDebounce<T>(
updatable?: boolean,
): T;
```

Part of [@data-client/hooks](https://www.npmjs.com/package/@data-client/hooks)
4 changes: 0 additions & 4 deletions docs/core/api/useLoading.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ Helps track loading state of imperative async functions.

## Usage

<PkgInstall pkgs="@data-client/hooks" />

<UseLoading />

## Eslint
Expand Down Expand Up @@ -52,8 +50,6 @@ export default function useLoading<
>(func: F, deps: readonly any[] = []): [F, boolean];
```

Part of [@data-client/hooks](https://www.npmjs.com/package/@data-client/hooks)

## Examples

### Github pagination
Expand Down
2 changes: 1 addition & 1 deletion docs/core/concepts/expiry-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ export default function TimePage({ id }) {
```

```tsx title="ShowTime"
import { useLoading } from '@data-client/hooks';
import { useLoading } from '@data-client/react';
import { TimedEntity } from './api/lastUpdated';
import TimePage from './TimePage';

Expand Down
2 changes: 1 addition & 1 deletion docs/core/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import Installation from '../shared/\_installation.mdx';
import StackBlitz from '@site/src/components/StackBlitz';
import Link from '@docusaurus/Link';

<PkgTabs pkgs="@data-client/react @data-client/test @data-client/hooks @data-client/rest" />
<PkgTabs pkgs="@data-client/react @data-client/test @data-client/rest" />

## Add provider at top-level component

Expand Down
2 changes: 1 addition & 1 deletion docs/core/guides/abort.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ abort.abort();
Sometimes a user has the opportunity to fill out a field that is used to affect the results of a network call.
If this is a text input, they could potentially type quite quickly, thus creating a lot of network requests.

Using [@data-client/hooks](https://www.npmjs.com/package/@data-client/hooks) package with [useCancelling()](/docs/api/useCancelling) will automatically cancel in-flight requests if the parameters
Using [useCancelling()](/docs/api/useCancelling) will automatically cancel in-flight requests if the parameters
change before the request is resolved.

<UseCancelling />
Expand Down
3 changes: 1 addition & 2 deletions docs/core/shared/_useCancelling.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ export const TodoResource = createResource({
```

```tsx title="TodoDetail" {6}
import { useSuspense } from '@data-client/react';
import { useCancelling } from '@data-client/hooks';
import { useSuspense, useCancelling } from '@data-client/react';
import { TodoResource } from './api/Todo';

export default function TodoDetail({ id }: { id: number }) {
Expand Down
3 changes: 1 addition & 2 deletions docs/core/shared/_useLoading.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ export default function PostForm({ onSubmit, loading, error }) {
```

```tsx title="PostCreate" {8}
import { useController } from '@data-client/react';
import { useLoading } from '@data-client/hooks';
import { useLoading, useController } from '@data-client/react';
import { PostResource } from './PostResource';
import PostForm from './PostForm';

Expand Down
2 changes: 1 addition & 1 deletion docs/rest/api/Collection.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ export const getPosts = new RestEndpoint({
```

```ts title="PostListLayout" collapsed
import { useLoading } from '@data-client/hooks';
import { useLoading } from '@data-client/react';

export default function PostListLayout({
postsByBob,
Expand Down
2 changes: 1 addition & 1 deletion docs/rest/api/Query.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const getPosts = new RestEndpoint({
```

```tsx title="NewPost" collapsed
import { useLoading } from '@data-client/hooks';
import { useLoading } from '@data-client/react';
import { getPosts } from './getPosts';

export default function NewPost({ user }: { user: string }) {
Expand Down
2 changes: 1 addition & 1 deletion docs/rest/guides/abort.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fetches that are no longer considered relevant. This can be hooked into fetch vi
Sometimes a user has the opportunity to fill out a field that is used to affect the results of a network call.
If this is a text input, they could potentially type quite quickly, thus creating a lot of network requests.

Using [@data-client/hooks](https://www.npmjs.com/package/@data-client/hooks) package with [useCancelling()](/docs/api/useCancelling) will automatically cancel in-flight requests if the parameters
Using [useCancelling()](/docs/api/useCancelling) will automatically cancel in-flight requests if the parameters
change before the request is resolved.

<UseCancelling />
Expand Down
2 changes: 1 addition & 1 deletion docs/rest/guides/optimistic-updates.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ export const increment = new RestEndpoint({
```

```tsx title="CounterPage" collapsed
import { useLoading } from '@data-client/hooks';
import { useLoading } from '@data-client/react';
import { getCount } from './count';
import { increment } from './increment';

Expand Down
2 changes: 1 addition & 1 deletion docs/rest/shared/_optimisticTransform.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const increment = new RestEndpoint({
```

```tsx title="CounterPage" collapsed
import { useLoading } from '@data-client/hooks';
import { useLoading } from '@data-client/react';
import { getCount } from './count';
import { increment } from './increment';

Expand Down
5 changes: 5 additions & 0 deletions packages/hooks/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Networking Hooks

[![CircleCI](https://circleci.com/gh/reactive/data-client/tree/master.svg?style=shield)](https://circleci.com/gh/reactive/data-client)
[![Coverage Status](https://img.shields.io/codecov/c/gh/reactive/data-client/master.svg?style=flat-square)](https://app.codecov.io/gh/reactive/data-client?branch=master)
[![npm downloads](https://img.shields.io/npm/dm/@data-client/hooks.svg?style=flat-square)](https://www.npmjs.com/package/@data-client/hooks)
Expand All @@ -14,6 +15,10 @@ Composable hooks for networking data

</div>

## 🚨 Repository Deprecated and Moved! 🚨

**This repository has been deprecated and is no longer actively maintained.** All hooks moved to [@data-client/react](https://www.npmjs.com/package/@data-client/react)

### [useCancelling()](https://dataclient.io/docs/api/useCancelling)

[Aborts](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) inflight request if the parameters change.
Expand Down
2 changes: 1 addition & 1 deletion packages/react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ For [REST](https://dataclient.io/rest), [GraphQL](https://dataclient.io/graphql)
## Installation

```bash
npm install --save @data-client/react @data-client/rest @data-client/test @data-client/hooks
npm install --save @data-client/react @data-client/rest @data-client/test
```

For more details, see [the Installation docs page](https://dataclient.io/docs/getting-started/installation).
Expand Down
81 changes: 81 additions & 0 deletions packages/react/src/hooks/__tests__/useCancelling.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { ArticleResource } from '__tests__/new';
import nock from 'nock';

import { renderHook, act } from '../../../../test';
import useCancelling from '../useCancelling';

describe('useCancelling()', () => {
const payload = {
id: '6',
title: 'lala',
};
const payload2 = {
id: '7',
title: 'second one',
};
beforeAll(() => {
jest.useFakeTimers({
legacyFakeTimers: true,
});
const mynock = nock(/.*/)
.persist()
.defaultReplyHeaders({
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Access-Token',
'Content-Type': 'application/json',
})
.options(/.*/)
.reply(200);

mynock
.get(`/article/${payload.id}`)
.delay(2000)
.reply(200, payload)
.get(`/article/${payload2.id}`)
.delay(2000)
.reply(200, payload2);
});
afterAll(() => {
jest.useRealTimers();
nock.cleanAll();
});

it('should abort when props change and resolve when kept the same', async () => {
const { result, rerender } = renderHook(
({ id }: { id: string }) => {
return useCancelling(ArticleResource.get, { id });
},
{ initialProps: { id: '6' } },
);
const firstendpoint = result.current;
const ogPromise = result.current({ id: '6' });
jest.advanceTimersByTime(10);
act(() => rerender({ id: '7' }));
expect(result.current).not.toBe(firstendpoint);
expect(ogPromise).rejects.toMatchInlineSnapshot(`[AbortError: Aborted]`);
const nextPromise = result.current({ id: '7' });
jest.advanceTimersByTime(2000);
await expect(nextPromise).resolves.toMatchInlineSnapshot(`
{
"id": "7",
"title": "second one",
}
`);
act(() => rerender({ id: '7' }));
});

it('should remain === if params does not change', () => {
const { result, rerender } = renderHook(
({ id }: { id: string }) => {
return useCancelling(ArticleResource.get, { id });
},
{ initialProps: { id: '6' } },
);
let lastendpoint = result.current;
act(() => rerender({ id: '6' }));
expect(result.current).toBe(lastendpoint);
lastendpoint = result.current;
act(() => rerender({ id: '6' }));
expect(result.current).toBe(lastendpoint);
});
});
53 changes: 53 additions & 0 deletions packages/react/src/hooks/__tests__/useDebounce.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { renderHook, act } from '../../../../test';
import useDebounce from '../useDebounce';

describe('useDebounce()', () => {
beforeAll(() => {
jest.useFakeTimers();
});
afterAll(() => {
jest.useRealTimers();
});

it('should not update until delay has passed', () => {
const { result, rerender } = renderHook(
({ value }: { value: string }) => {
return useDebounce(value, 100);
},
{ initialProps: { value: 'initial' } },
);
expect(result.current).toBe('initial');
jest.advanceTimersByTime(10);
rerender({ value: 'next' });
rerender({ value: 'third' });
expect(result.current).toBe('initial');
act(() => {
jest.advanceTimersByTime(100);
});
expect(result.current).toBe('third');
});

it('should never update when updatable is false', () => {
const { result, rerender } = renderHook(
({ value, updatable }: { value: string; updatable: boolean }) => {
return useDebounce(value, 100, updatable);
},
{ initialProps: { value: 'initial', updatable: false } },
);
expect(result.current).toBe('initial');
jest.advanceTimersByTime(10);
rerender({ value: 'next', updatable: false });
act(() => {
jest.advanceTimersByTime(100);
});
expect(result.current).toBe('initial');
rerender({ value: 'third', updatable: true });
expect(result.current).toBe('initial');
jest.advanceTimersByTime(10);
expect(result.current).toBe('initial');
act(() => {
jest.advanceTimersByTime(100);
});
expect(result.current).toBe('third');
});
});
Loading

0 comments on commit 0e6b6b5

Please sign in to comment.