Skip to content

Commit

Permalink
Merge branch 'main' into react-await/garbage-collectable
Browse files Browse the repository at this point in the history
  • Loading branch information
manudeli authored Dec 25, 2023
2 parents b97fb7b + 45ce93f commit c753dfb
Show file tree
Hide file tree
Showing 45 changed files with 642 additions and 166 deletions.
5 changes: 5 additions & 0 deletions .changeset/slimy-chicken-sneeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@suspensive/react": minor
---

feat(react): add DevMode
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"]
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
"editor.formatOnSave": true
}
4 changes: 2 additions & 2 deletions configs/eslint-config-js/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/** @type {import('eslint').Linter.Config} */
module.exports = {
root: true,
extends: ['plugin:import/recommended', './no-import.js'],
extends: ['plugin:import/recommended', 'plugin:import/recommended', './no-import.js'],
plugins: ['import'],
rules: {
'sort-imports': ['error', { ignoreDeclarationSort: true }],
'import/no-duplicates': 'error',
'import/no-cycle': 'error',
'import/no-duplicates': ['error', { 'prefer-inline': true }],
'import/order': [
'warn',
{
Expand Down
6 changes: 3 additions & 3 deletions configs/eslint-config-ts/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @type {import('eslint').Linter.Config} */
module.exports = {
root: true,
extends: ['plugin:import/typescript', './no-import.js'],
extends: ['plugin:import/recommended', 'plugin:import/typescript', './no-import.js'],
plugins: ['import'],
settings: {
'import/resolver': {
Expand All @@ -10,14 +10,14 @@ module.exports = {
},
overrides: [
{
files: ['*.test-d.ts*', '*.test-d.ts*'],
files: ['*.test-d.ts*'],
rules: { 'import/no-unresolved': ['error', { ignore: ['tsd'] }] },
},
],
rules: {
'sort-imports': ['error', { ignoreDeclarationSort: true }],
'import/no-duplicates': 'error',
'import/no-cycle': 'error',
'import/no-duplicates': ['error', { 'prefer-inline': true }],
'import/order': [
'error',
{
Expand Down
3 changes: 1 addition & 2 deletions configs/test-utils/src/ThrowError.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { PropsWithChildren } from 'react'
import { useEffect, useLayoutEffect, useRef, useState } from 'react'
import { type PropsWithChildren, useEffect, useLayoutEffect, useRef, useState } from 'react'

export const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect

Expand Down
83 changes: 83 additions & 0 deletions docs/v1/src/pages/docs/react/DevMode.en.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Callout } from 'nextra/components'

## `<DevMode/>`

<Callout type="warning">

`<DevMode/>` is experimental feature, this interfaces could be changed

</Callout>

`<DevMode/>` can control `<Suspense/>`, `<ErrorBoundary/>` to develop each fallback easily
This will work in only development mode, and in production mode(on build app), these apis will be gratefully removed

### Setup

After setup `<DevMode/>`, We can use devMode prop for each component

```jsx /DevMode/
import { Suspensive, SuspensiveProvider, DevMode } from '@suspensive/react'

const App = () => {
const [suspensive] = useState(() => new Suspensive())

return (
<SuspensiveProvider value={suspensive}>
{/** in children, we can use devMode now */}
<DevMode />
</SuspensiveProvider>
)
}
```

#### `<Suspense/>` devMode prop

```jsx /devMode/
import { Suspense } from '@suspensive/react'

const Example = () => (
<Suspense
fallback={<>loading...</>}
devMode={{
// use devMode prop, and click `<DevMode/>` in display
showFallback: true,
}}
>
children
</Suspense>
)
```

#### `<ErrorBoundary/>` devMode prop

```jsx /devMode/
import { ErrorBoundary } from '@suspensive/react'

const Example = () => (
<ErrorBoundary
fallback={({ error }) => <>{error.message}</>}
devMode={{
// use devMode prop, and click `<DevMode/>` in display
showFallback: true,
}}
>
children
</ErrorBoundary>
)
```

```jsx /devMode/
import { ErrorBoundary } from '@suspensive/react'

const Example = () => (
<ErrorBoundary
fallback={({ error }) => <>{error.message}</>}
devMode={{
// use devMode prop, and click `<DevMode/>` in display
showFallback: { after: 2000 },
}}
>
children
</ErrorBoundary>
)
```
83 changes: 83 additions & 0 deletions docs/v1/src/pages/docs/react/DevMode.ko.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Callout } from 'nextra/components'

## `<DevMode/>`

<Callout type="warning">

`<DevMode/>`는 실험 기능이므로 이 인터페이스는 변경될 수 있습니다

</Callout>

`<DevMode/>`는 오직 `<Suspense/>`, `<ErrorBoundary/>` 각각의 fallback을 쉽게 개발하기 위해 컨트롤할 수 있습니다.
이것은 오직 development 모드에서만 동작합니다. production 모드에서는(앱 build시에), 이 api들은 잘 제거됩니다.

### Setup

`<DevMode/>`를 설정하고, 각 컴포넌트의 devMode prop을 사용할 수 있습니다

```jsx /DevMode/
import { Suspensive, SuspensiveProvider, DevMode } from '@suspensive/react'

const App = () => {
const [suspensive] = useState(() => new Suspensive())

return (
<SuspensiveProvider value={suspensive}>
{/** in children, we can use devMode now */}
<DevMode />
</SuspensiveProvider>
)
}
```

#### `<Suspense/>` devMode prop

```jsx /devMode/
import { Suspense } from '@suspensive/react'

const Example = () => (
<Suspense
fallback={<>loading...</>}
devMode={{
// use devMode prop, and click `<DevMode/>` in display
showFallback: true,
}}
>
children
</Suspense>
)
```

#### `<ErrorBoundary/>` devMode prop

```jsx /devMode/
import { ErrorBoundary } from '@suspensive/react'

const Example = () => (
<ErrorBoundary
fallback={({ error }) => <>{error.message}</>}
devMode={{
// use devMode prop, and click `<DevMode/>` in display
showFallback: true,
}}
>
children
</ErrorBoundary>
)
```

```jsx /devMode/
import { ErrorBoundary } from '@suspensive/react'

const Example = () => (
<ErrorBoundary
fallback={({ error }) => <>{error.message}</>}
devMode={{
// use devMode prop, and click `<DevMode/>` in display
showFallback: { after: 2000 },
}}
>
children
</ErrorBoundary>
)
```
2 changes: 0 additions & 2 deletions docs/v1/src/pages/docs/react/SuspensiveProvider.en.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { Callout } from 'nextra/components'

# SuspensiveProvider

This component controls the settings of the components provided by Suspensive (Suspense, Delay, etc.) at once.
Expand Down
2 changes: 0 additions & 2 deletions docs/v1/src/pages/docs/react/SuspensiveProvider.ko.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { Callout } from 'nextra/components'

# SuspensiveProvider

이 컴포넌트는 Suspensive가 제공하는 컴포넌트들(Suspense, Delay 등)의 설정을 한 번에 제어합니다.
Expand Down
1 change: 1 addition & 0 deletions docs/v1/src/pages/docs/react/_meta.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
"ErrorBoundaryGroup": { "title": "<ErrorBoundaryGroup/>" },
"Delay": { "title": "<Delay/>" },
"SuspensiveProvider": { "title": "<SuspensiveProvider/>" },
"DevMode": { "title": "<DevMode/>" },
"wrap": { "title": "wrap" }
}
1 change: 1 addition & 0 deletions docs/v1/src/pages/docs/react/_meta.ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
"ErrorBoundaryGroup": { "title": "<ErrorBoundaryGroup/>" },
"Delay": { "title": "<Delay/>" },
"SuspensiveProvider": { "title": "<SuspensiveProvider/>" },
"DevMode": { "title": "<DevMode/>" },
"wrap": { "title": "wrap" }
}
3 changes: 1 addition & 2 deletions packages/react-await/src/Await.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { FunctionComponent } from 'react'
import { useMemo } from 'react'
import { type FunctionComponent, useMemo } from 'react'
import { useSyncExternalStore } from 'use-sync-external-store/shim'
import type { Tuple } from './utility-types'
import { hashKey } from './utils'
Expand Down
3 changes: 1 addition & 2 deletions packages/react-await/src/utils/hashKey.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { Key } from '../Await'
import type { PlainObject } from './isPlainObject'
import { isPlainObject } from './isPlainObject'
import { type PlainObject, isPlainObject } from './isPlainObject'

export const hashKey = (key: Key) =>
JSON.stringify(key, (_, val) =>
Expand Down
3 changes: 1 addition & 2 deletions packages/react-image/src/Image.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { ComponentProps } from 'react'
import { forwardRef } from 'react'
import { type ComponentProps, forwardRef } from 'react'
import { useLoad } from './Load'

type ImageProps = ComponentProps<'img'>
Expand Down
3 changes: 1 addition & 2 deletions packages/react-query/src/QueryAsyncBoundary.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { AsyncBoundary } from '@suspensive/react'
import { useQueryErrorResetBoundary } from '@tanstack/react-query'
import type { ComponentPropsWithoutRef, ComponentRef } from 'react'
import { forwardRef } from 'react'
import { type ComponentPropsWithoutRef, type ComponentRef, forwardRef } from 'react'

const BaseQueryAsyncBoundary = forwardRef<
ComponentRef<typeof AsyncBoundary>,
Expand Down
3 changes: 1 addition & 2 deletions packages/react-query/src/QueryErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ErrorBoundary } from '@suspensive/react'
import { useQueryErrorResetBoundary } from '@tanstack/react-query'
import type { ComponentPropsWithoutRef, ComponentRef } from 'react'
import { forwardRef } from 'react'
import { type ComponentPropsWithoutRef, type ComponentRef, forwardRef } from 'react'

/**
* This component wrapping QueryErrorResetBoundary of @tanstack/react-query with @suspensive/react's ErrorBoundary.
Expand Down
15 changes: 8 additions & 7 deletions packages/react-query/src/useSuspenseInfiniteQuery.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type {
InfiniteData,
QueryFunction,
QueryKey,
UseInfiniteQueryOptions,
UseInfiniteQueryResult,
import {
type InfiniteData,
type QueryFunction,
type QueryKey,
type UseInfiniteQueryOptions,
type UseInfiniteQueryResult,
parseQueryArgs,
useInfiniteQuery,
} from '@tanstack/react-query'
import { parseQueryArgs, useInfiniteQuery } from '@tanstack/react-query'

export type BaseUseSuspenseInfiniteQueryResult<TData = unknown> = Omit<
UseInfiniteQueryResult<TData>,
Expand Down
10 changes: 8 additions & 2 deletions packages/react-query/src/useSuspenseQueries.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
// TODO: remove this eslint
/* eslint-disable @typescript-eslint/naming-convention */
import type { QueryFunction, QueryKey, UseQueryOptions, UseQueryResult } from '@tanstack/react-query'
import { useQueries } from '@tanstack/react-query'

import {
type QueryFunction,
type QueryKey,
type UseQueryOptions,
type UseQueryResult,
useQueries,
} from '@tanstack/react-query'
import type { UseSuspenseQueryResultOnLoading, UseSuspenseQueryResultOnSuccess } from './useSuspenseQuery'

// Avoid TS depth-limit error in case of large array literal
Expand Down
10 changes: 8 additions & 2 deletions packages/react-query/src/useSuspenseQuery.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type { QueryFunction, QueryKey, UseQueryOptions, UseQueryResult } from '@tanstack/react-query'
import { parseQueryArgs, useQuery } from '@tanstack/react-query'
import {
type QueryFunction,
type QueryKey,
type UseQueryOptions,
type UseQueryResult,
parseQueryArgs,
useQuery,
} from '@tanstack/react-query'

export interface BaseUseSuspenseQueryResult<TData = unknown>
extends Omit<UseQueryResult<TData>, 'error' | 'isError' | 'isFetching'> {
Expand Down
3 changes: 1 addition & 2 deletions packages/react/src/AsyncBoundary.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { ERROR_MESSAGE, FALLBACK, Suspend, TEXT, ThrowError } from '@suspensive/test-utils'
import { act, render, waitFor } from '@testing-library/react'
import ms from 'ms'
import type { ComponentProps } from 'react'
import { createElement } from 'react'
import { type ComponentProps, createElement } from 'react'
import { createRoot } from 'react-dom/client'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { AsyncBoundary, withAsyncBoundary } from '.'
Expand Down
18 changes: 9 additions & 9 deletions packages/react/src/AsyncBoundary.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import type { ComponentRef, SuspenseProps } from 'react'
import { forwardRef } from 'react'
import { ErrorBoundary } from './ErrorBoundary'
import type { ErrorBoundaryProps } from './ErrorBoundary'
import { type ComponentRef, type SuspenseProps, forwardRef } from 'react'
import { ErrorBoundary, type ErrorBoundaryProps } from './ErrorBoundary'
import { Suspense } from './Suspense'
import type { PropsWithoutDevMode } from './utility-types'

/**
* @deprecated Use SuspenseProps and ErrorBoundaryProps as alternatives
*/
export type AsyncBoundaryProps = Omit<SuspenseProps, 'fallback'> &
Omit<ErrorBoundaryProps, 'fallback'> & {
pendingFallback?: SuspenseProps['fallback']
rejectedFallback: ErrorBoundaryProps['fallback']
}
export interface AsyncBoundaryProps
extends Omit<PropsWithoutDevMode<SuspenseProps>, 'fallback'>,
Omit<PropsWithoutDevMode<ErrorBoundaryProps>, 'fallback'> {
pendingFallback?: SuspenseProps['fallback']
rejectedFallback: ErrorBoundaryProps['fallback']
}

const BaseAsyncBoundary = forwardRef<ComponentRef<typeof ErrorBoundary>, AsyncBoundaryProps>(
({ pendingFallback, rejectedFallback, children, ...errorBoundaryProps }, resetRef) => (
Expand Down
7 changes: 3 additions & 4 deletions packages/react/src/Delay.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import type { PropsWithChildren } from 'react'
import { useContext, useState } from 'react'
import { type PropsWithChildren, useContext, useState } from 'react'
import { DelayDefaultOptionsContext } from './contexts'
import { useTimeout } from './hooks'

export type DelayProps = PropsWithChildren<{
export interface DelayProps extends PropsWithChildren {
ms?: number
}>
}

export const Delay = ({ ms, children }: DelayProps) => {
const delayDefaultOptions = useContext(DelayDefaultOptionsContext)
Expand Down
Loading

0 comments on commit c753dfb

Please sign in to comment.