From 22e634a30e27f4b3be2e7622e69c0a8cb1caf8ce Mon Sep 17 00:00:00 2001 From: Jonghyeon Ko Date: Thu, 19 Oct 2023 00:46:09 +0900 Subject: [PATCH] fix(react): remove await --- .github/workflows/ci.yml | 4 +- docs/src/pages/docs/_meta.en.json | 3 +- docs/src/pages/docs/_meta.ko.json | 3 +- .../docs/{react => react-await}/Await.en.mdx | 3 +- .../docs/{react => react-await}/Await.ko.mdx | 3 +- docs/src/pages/docs/react-await/_meta.en.json | 3 + docs/src/pages/docs/react-await/_meta.ko.json | 10 + .../docs/react-await/installation.en.mdx | 7 + .../docs/react-await/installation.ko.mdx | 7 + docs/src/pages/docs/react/_meta.en.json | 3 +- docs/src/pages/docs/react/_meta.ko.json | 3 +- docs/src/pages/docs/react/installation.ko.mdx | 4 +- package.json | 2 + packages/react-await/.eslintrc.cjs | 6 + packages/react-await/CHANGELOG.md | 211 +++++++++++++++ packages/react-await/LICENSE | 21 ++ packages/react-await/README.ko.md | 15 ++ packages/react-await/README.md | 15 ++ packages/react-await/package.json | 78 ++++++ .../src}/Await.spec.tsx | 4 +- .../src}/Await.tsx | 4 +- .../experimental => react-await/src}/index.ts | 0 packages/react-await/src/types/Tuple.ts | 1 + packages/react-await/src/types/index.ts | 2 + packages/react-await/src/utils/assert.spec.ts | 36 +++ packages/react-await/src/utils/assert.ts | 19 ++ .../src/utils/hasResetKeysChanged.spec.ts | 53 ++++ .../src/utils/hasResetKeysChanged.ts | 2 + .../react-await/src/utils/hashKey.spec.ts | 26 ++ packages/react-await/src/utils/hashKey.ts | 15 ++ packages/react-await/src/utils/index.ts | 3 + .../src/utils/isPlainObject.spec.ts | 44 ++++ .../react-await/src/utils/isPlainObject.ts | 29 +++ packages/react-await/src/utils/toTest.tsx | 25 ++ packages/react-await/test.setup.ts | 9 + packages/react-await/tsconfig.json | 7 + packages/react-await/tsup.config.ts | 4 + packages/react-await/vitest.config.ts | 4 + packages/react-query/package.json | 1 + packages/react/package.json | 14 +- pnpm-lock.yaml | 242 +++++++++++++++--- turbo.json | 1 + 42 files changed, 882 insertions(+), 64 deletions(-) rename docs/src/pages/docs/{react => react-await}/Await.en.mdx (90%) rename docs/src/pages/docs/{react => react-await}/Await.ko.mdx (90%) create mode 100644 docs/src/pages/docs/react-await/_meta.en.json create mode 100644 docs/src/pages/docs/react-await/_meta.ko.json create mode 100644 docs/src/pages/docs/react-await/installation.en.mdx create mode 100644 docs/src/pages/docs/react-await/installation.ko.mdx create mode 100644 packages/react-await/.eslintrc.cjs create mode 100644 packages/react-await/CHANGELOG.md create mode 100644 packages/react-await/LICENSE create mode 100644 packages/react-await/README.ko.md create mode 100644 packages/react-await/README.md create mode 100644 packages/react-await/package.json rename packages/{react/src/experimental => react-await/src}/Await.spec.tsx (97%) rename packages/{react/src/experimental => react-await/src}/Await.tsx (98%) rename packages/{react/src/experimental => react-await/src}/index.ts (100%) create mode 100644 packages/react-await/src/types/Tuple.ts create mode 100644 packages/react-await/src/types/index.ts create mode 100644 packages/react-await/src/utils/assert.spec.ts create mode 100644 packages/react-await/src/utils/assert.ts create mode 100644 packages/react-await/src/utils/hasResetKeysChanged.spec.ts create mode 100644 packages/react-await/src/utils/hasResetKeysChanged.ts create mode 100644 packages/react-await/src/utils/hashKey.spec.ts create mode 100644 packages/react-await/src/utils/hashKey.ts create mode 100644 packages/react-await/src/utils/index.ts create mode 100644 packages/react-await/src/utils/isPlainObject.spec.ts create mode 100644 packages/react-await/src/utils/isPlainObject.ts create mode 100644 packages/react-await/src/utils/toTest.tsx create mode 100644 packages/react-await/test.setup.ts create mode 100644 packages/react-await/tsconfig.json create mode 100644 packages/react-await/tsup.config.ts create mode 100644 packages/react-await/vitest.config.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aefc99ce0..5c2519f89 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - command: ['pnpm lint', 'pnpm lint:pub', 'pnpm test', 'pnpm test:tsd', 'pnpm type:check'] + command: ['lint', 'lint:attw', 'lint:pub', 'test', 'test:tsd', 'type:check'] steps: - uses: actions/checkout@v3 - uses: pnpm/action-setup@v2 @@ -31,4 +31,4 @@ jobs: - run: pnpm install --frozen-lockfile - run: pnpm prepack - name: Run commands - run: ${{ matrix.command }} + run: pnpm ${{ matrix.command }} diff --git a/docs/src/pages/docs/_meta.en.json b/docs/src/pages/docs/_meta.en.json index 057a41ff3..1e5d0e784 100644 --- a/docs/src/pages/docs/_meta.en.json +++ b/docs/src/pages/docs/_meta.en.json @@ -3,5 +3,6 @@ "intro": "Getting Started", "links": "Related Links", "react": "@suspensive/react", - "react-query": "@suspensive/react-query" + "react-query": "@suspensive/react-query", + "react-await": "@suspensive/react-await" } diff --git a/docs/src/pages/docs/_meta.ko.json b/docs/src/pages/docs/_meta.ko.json index 4e29da93f..98a052f62 100644 --- a/docs/src/pages/docs/_meta.ko.json +++ b/docs/src/pages/docs/_meta.ko.json @@ -3,5 +3,6 @@ "intro": "시작하기", "links": "관련 링크", "react": "@suspensive/react", - "react-query": "@suspensive/react-query" + "react-query": "@suspensive/react-query", + "react-await": "@suspensive/react-await" } diff --git a/docs/src/pages/docs/react/Await.en.mdx b/docs/src/pages/docs/react-await/Await.en.mdx similarity index 90% rename from docs/src/pages/docs/react/Await.en.mdx rename to docs/src/pages/docs/react-await/Await.en.mdx index 007ba8eba..3421a7a4c 100644 --- a/docs/src/pages/docs/react/Await.en.mdx +++ b/docs/src/pages/docs/react-await/Await.en.mdx @@ -14,7 +14,8 @@ Afterwards, when the Promise is fulfilled, the guaranteed awaited data can be us Additionally, this data is cached in the received key and can be used immediately without pending when reused. ```tsx -import { Await, Suspense } from '@supensive/react' +import { Await } from '@suspensive/react-await' +import { Suspense } from '@suspensive/react' const getPost = (postId: number) => fetch(`/post/${postId}`).then((res) => res.json()) as Post diff --git a/docs/src/pages/docs/react/Await.ko.mdx b/docs/src/pages/docs/react-await/Await.ko.mdx similarity index 90% rename from docs/src/pages/docs/react/Await.ko.mdx rename to docs/src/pages/docs/react-await/Await.ko.mdx index 80ee2a502..2b6600c35 100644 --- a/docs/src/pages/docs/react/Await.ko.mdx +++ b/docs/src/pages/docs/react-await/Await.ko.mdx @@ -14,7 +14,8 @@ import { Callout } from 'nextra/components' 또한 이 data는 받은 키에 cache되어 재사용하는 경우 pending없이 즉시 사용할 수 있습니다. ```tsx -import { Await, Suspense } from '@supensive/react' +import { Await } from '@suspensive/react-await' +import { Suspense } from '@suspensive/react' const getPost = (postId: number) => fetch(`/post/${postId}`).then((res) => res.json()) as Post diff --git a/docs/src/pages/docs/react-await/_meta.en.json b/docs/src/pages/docs/react-await/_meta.en.json new file mode 100644 index 000000000..83dea08d8 --- /dev/null +++ b/docs/src/pages/docs/react-await/_meta.en.json @@ -0,0 +1,3 @@ +{ + "Await": { "title": "" } +} diff --git a/docs/src/pages/docs/react-await/_meta.ko.json b/docs/src/pages/docs/react-await/_meta.ko.json new file mode 100644 index 000000000..c9c646361 --- /dev/null +++ b/docs/src/pages/docs/react-await/_meta.ko.json @@ -0,0 +1,10 @@ +{ + "installation": { "title": "설치하기" }, + "Suspense": { "title": "" }, + "ErrorBoundary": { "title": "" }, + "ErrorBoundaryGroup": { "title": "" }, + "Delay": { "title": "" }, + "AsyncBoundary": { "title": "" }, + "SuspensiveProvider": { "title": "" }, + "Await": { "title": "" } +} diff --git a/docs/src/pages/docs/react-await/installation.en.mdx b/docs/src/pages/docs/react-await/installation.en.mdx new file mode 100644 index 000000000..52de70119 --- /dev/null +++ b/docs/src/pages/docs/react-await/installation.en.mdx @@ -0,0 +1,7 @@ +# Installation + +@suspensive/react-await package lives in npm. To install the latest stable version, run the following command + +```shell npm2yarn +npm install @suspensive/react-await +``` diff --git a/docs/src/pages/docs/react-await/installation.ko.mdx b/docs/src/pages/docs/react-await/installation.ko.mdx new file mode 100644 index 000000000..8e50024fd --- /dev/null +++ b/docs/src/pages/docs/react-await/installation.ko.mdx @@ -0,0 +1,7 @@ +# 설치하기 + +@suspensive/react-await는 npm에 있습니다. 최신 안정버전을 설치하기 위해 아래 커맨드를 실행하세요 + +```shell npm2yarn +npm install @suspensive/react-await +``` diff --git a/docs/src/pages/docs/react/_meta.en.json b/docs/src/pages/docs/react/_meta.en.json index a7cc8be71..86bd8571c 100644 --- a/docs/src/pages/docs/react/_meta.en.json +++ b/docs/src/pages/docs/react/_meta.en.json @@ -5,6 +5,5 @@ "ErrorBoundaryGroup": { "title": "" }, "Delay": { "title": "" }, "AsyncBoundary": { "title": "" }, - "SuspensiveProvider": { "title": "" }, - "Await": { "title": "" } + "SuspensiveProvider": { "title": "" } } diff --git a/docs/src/pages/docs/react/_meta.ko.json b/docs/src/pages/docs/react/_meta.ko.json index c9c646361..18866a309 100644 --- a/docs/src/pages/docs/react/_meta.ko.json +++ b/docs/src/pages/docs/react/_meta.ko.json @@ -5,6 +5,5 @@ "ErrorBoundaryGroup": { "title": "" }, "Delay": { "title": "" }, "AsyncBoundary": { "title": "" }, - "SuspensiveProvider": { "title": "" }, - "Await": { "title": "" } + "SuspensiveProvider": { "title": "" } } diff --git a/docs/src/pages/docs/react/installation.ko.mdx b/docs/src/pages/docs/react/installation.ko.mdx index ab6ef72fd..8e50024fd 100644 --- a/docs/src/pages/docs/react/installation.ko.mdx +++ b/docs/src/pages/docs/react/installation.ko.mdx @@ -1,7 +1,7 @@ # 설치하기 -@suspensive/react는 npm에 있습니다. 최신 안정버전을 설치하기 위해 아래 커맨드를 실행하세요 +@suspensive/react-await는 npm에 있습니다. 최신 안정버전을 설치하기 위해 아래 커맨드를 실행하세요 ```shell npm2yarn -npm install @suspensive/react +npm install @suspensive/react-await ``` diff --git a/package.json b/package.json index 476e0142b..074691e9f 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "format": "prettier --write \"**/*.{ts,tsx,md}\"", "graph": "rimraf ./graph && mkdir graph && turbo run build --graph=graph/index.html", "lint": "turbo run lint", + "lint:attw": "turbo run lint:attw", "lint:pack": "packlint sort -R", "lint:pub": "turbo run lint:pub", "postinstall": "husky install", @@ -44,6 +45,7 @@ "type:check": "turbo run type:check --parallel" }, "devDependencies": { + "@arethetypeswrong/cli": "^0.12.2", "@changesets/cli": "^2.26.1", "@commitlint/cli": "^17.6.1", "@commitlint/config-conventional": "^17.6.1", diff --git a/packages/react-await/.eslintrc.cjs b/packages/react-await/.eslintrc.cjs new file mode 100644 index 000000000..7d0206f78 --- /dev/null +++ b/packages/react-await/.eslintrc.cjs @@ -0,0 +1,6 @@ +/** @type {import('eslint').Linter.Config} */ +module.exports = { + root: true, + extends: ['@suspensive/eslint-config/react-ts'], + ignorePatterns: ['*.js*', 'dist', 'coverage'], +} diff --git a/packages/react-await/CHANGELOG.md b/packages/react-await/CHANGELOG.md new file mode 100644 index 000000000..27a94b183 --- /dev/null +++ b/packages/react-await/CHANGELOG.md @@ -0,0 +1,211 @@ +# @suspensive/react + +## 1.16.1 + +### Patch Changes + +- d415299: chore: remove docs in packages + +## 1.16.0 + +### Minor Changes + +- a711c19: feat(react): add useErrorBoundaryFallbackProps + +## 1.15.5 + +### Patch Changes + +- 62c3384: chore(eslint): add no-duplicates, consistent-type-imports + +## 1.15.4 + +### Patch Changes + +- ba1e1a6: refactor(react): to easier code + +## 1.15.3 + +### Patch Changes + +- b05b4e2: docs(react): update doc for Delay +- e1e9a6b: docs(react): update doc for ErrorBoundaryGroup + +## 1.15.2 + +### Patch Changes + +- cbfbc02: docs(docusaurus): add npm2yarn plugin +- cfcafd2: docs(react): update tips as admonitions + +## 1.15.1 + +### Patch Changes + +- 5dfdf71: fix: remove awaitClient from ErrorBoundary +- c9bc99d: docs: update experimental feature mark as admonitions of docusaurus + +## 1.15.0 + +### Minor Changes + +- b431a4d: feat(react): add useErrorBoundary + +## 1.14.9 + +## 1.14.8 + +### Patch Changes + +- dd75647: feat(react): add getError, remove unnecessary generic +- a803b48: fix(react): fix ErrorBoundary reset using render prop + +## 1.14.7 + +### Patch Changes + +- 085cbe6: refactor(react): apply assert + +## 1.14.6 + +### Patch Changes + +- eac6832: fix(react): add assertion function to assert condition + +## 1.14.5 + +### Patch Changes + +- da0bd52: refactor(react): clarify variable name +- 2c30f6d: refactor(react): add useSetTimeout to reduce code + +## 1.14.4 + +### Patch Changes + +- 8d8ef53: fix(react): object that elment of key don't care field's order by hashKey +- 482cfc4: fix(react): update BaseErrorBoundary method simply +- d636e85: fix(react): ErrorBoundary should catch null thrown by children +- 8d8ef53: fix(react): replace useEffect to use-sync-external-store + +## 1.14.3 + +### Patch Changes + +- da62f3a: refactor(react): merge hoc's code into original component file + +## 1.14.2 + +### Patch Changes + +- ada618e: chore(package.json): more detail + +## 1.14.1 + +### Patch Changes + +- c5906c9: refactor(react, react-query): remove **test** directory to collocate + +## 1.14.0 + +### Minor Changes + +- 252d1d3: fix(react): rename useSuspenseCache to useAwait, suspenseCache to SuspensiveCache + +## 1.13.0 + +### Minor Changes + +- 95be8a2: fix(react): change experimental Delay, SuspensiveProvider to stable + +## 1.12.2 + +### Patch Changes + +- 6237e94: feat(vitest): add @suspensive/vitest generating named config automatically by packageJson.name +- 6c5e097: ci(test): migrate jest to vitest + +## 1.12.1 + +### Patch Changes + +- 7109191: fix(esm): cjs to esm as default + +## 1.12.0 + +### Minor Changes + +- e3df644: feat(react): add ErrorBoundaryFallbackProps type + +### Patch Changes + +- f4b1ac7: fix(react): enable hook in ErrorBoundary +- 8c23785: refactor(eslint, tsconfig): simply + +## 1.11.7 + +### Patch Changes + +- f23a241: fix(typescript): update version from v4 to v5 + +## 1.11.6 + +### Patch Changes + +- eb8b6a9: fix(react, react-query): remove unnecessary files by package.json's files + +## 1.11.5 + +### Patch Changes + +- resolve @suspensive/tsup error + +## 1.11.4 + +### Patch Changes + +- 80cc215: chore(bundler): migrate from rollup to tsup + +## 1.11.4-beta.0 + +### Patch Changes + +- 5b87ae4: chore(bundler): migrate from rollup to tsup + +## 1.11.3 + +### Patch Changes + +- a9b97c2: fix(react): remove ErrorBoundaryGroup's unnecessary rerender by usePrevious, remove not on purpose situation's group.reset by isMounted's side effect + +## 1.11.2 + +### Patch Changes + +- ef0350c: fix(react): fix useErrorBoundaryGroup to guarantee parent ErrorBoundaryGroup + +## 1.11.1 + +## 1.11.0 + +### Minor Changes + +- a89dd4f: feat(react): add useSuspenseCache, suspenseCache(experimental) + +## 1.10.0 + +## 1.9.6 + +### Patch Changes + +- 1a9f364: fix(react): add next.js appRouter 'use client' directive + +## 1.9.5 + +## 1.9.4 + +## 1.9.3 + +### Patch Changes + +- 6e99b89: changelog initialization diff --git a/packages/react-await/LICENSE b/packages/react-await/LICENSE new file mode 100644 index 000000000..d8a172f84 --- /dev/null +++ b/packages/react-await/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Suspensive + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/react-await/README.ko.md b/packages/react-await/README.ko.md new file mode 100644 index 000000000..4995a9c98 --- /dev/null +++ b/packages/react-await/README.ko.md @@ -0,0 +1,15 @@ +# 라이브러리 소개 + +@suspensive/react는 React suspense를 쉽게 사용하기 위한 모든 컴포넌트를 제공합니다. + +[![npm version](https://img.shields.io/npm/v/@suspensive/react?color=000&labelColor=000&logo=npm&label=)](https://www.npmjs.com/package/@suspensive/react) +[![npm](https://img.shields.io/npm/dm/@suspensive/react?color=000&labelColor=000)](https://www.npmjs.com/package/@suspensive/react) +[![npm bundle size](https://img.shields.io/bundlephobia/minzip/@suspensive/react?color=000&labelColor=000)](https://www.npmjs.com/package/@suspensive/react) + +## 설치하기 + +@suspensive/react 는 npm에 있습니다. 최신 안정버전을 설치하기 위해 아래 커맨드를 실행하세요 + +```shell npm2yarn +npm install @suspensive/react +``` diff --git a/packages/react-await/README.md b/packages/react-await/README.md new file mode 100644 index 000000000..a3276e8f6 --- /dev/null +++ b/packages/react-await/README.md @@ -0,0 +1,15 @@ +# Introduction + +@suspensive/react provide all components to use React Suspense easily. + +[![npm version](https://img.shields.io/npm/v/@suspensive/react?color=000&labelColor=000&logo=npm&label=)](https://www.npmjs.com/package/@suspensive/react) +[![npm](https://img.shields.io/npm/dm/@suspensive/react?color=000&labelColor=000)](https://www.npmjs.com/package/@suspensive/react) +[![npm bundle size](https://img.shields.io/bundlephobia/minzip/@suspensive/react?color=000&labelColor=000)](https://www.npmjs.com/package/@suspensive/react) + +## Installation + +@suspensive/react lives in npm. To install the latest stable version, run the following command + +```shell npm2yarn +npm install @suspensive/react +``` diff --git a/packages/react-await/package.json b/packages/react-await/package.json new file mode 100644 index 000000000..45d398f8e --- /dev/null +++ b/packages/react-await/package.json @@ -0,0 +1,78 @@ +{ + "name": "@suspensive/react-await", + "version": "0.0.0", + "description": "Useful interfaces for React Suspense", + "keywords": [ + "suspensive", + "react" + ], + "homepage": "https://suspensive.org", + "bugs": "https://github.com/suspensive/react/issues", + "repository": { + "type": "git", + "url": "https://github.com/suspensive/react.git", + "directory": "packages/react" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/manudeli" + }, + "license": "MIT", + "author": { + "name": "Jonghyeon Ko", + "email": "manudeli.ko@gmail.com" + }, + "sideEffects": false, + "type": "module", + "exports": { + ".": { + "import": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.cjs" + } + }, + "./package.json": "./package.json" + }, + "main": "dist/index.cjs", + "types": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "tsup", + "build:watch": "tsup --watch", + "clean": "rimraf ./dist && rimraf ./coverage", + "lint": "eslint \"**/*.ts*\"", + "lint:attw": "attw --pack", + "lint:pub": "publint --strict", + "prepack": "pnpm build", + "test": "vitest run --coverage", + "test:watch": "vitest --ui --coverage.enabled=true", + "type:check": "tsc --noEmit" + }, + "dependencies": { + "use-sync-external-store": "^1.2.0" + }, + "devDependencies": { + "@suspensive/react": "workspace:*", + "@suspensive/tsup": "workspace:*", + "@suspensive/vitest": "workspace:*", + "@types/node": "^18.16.2", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.1", + "@types/use-sync-external-store": "^0.0.4", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17 || ^18" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/react/src/experimental/Await.spec.tsx b/packages/react-await/src/Await.spec.tsx similarity index 97% rename from packages/react/src/experimental/Await.spec.tsx rename to packages/react-await/src/Await.spec.tsx index e08b55314..bf990a4de 100644 --- a/packages/react/src/experimental/Await.spec.tsx +++ b/packages/react-await/src/Await.spec.tsx @@ -1,7 +1,7 @@ +import { ErrorBoundary, Suspense } from '@suspensive/react' import { act, render, screen, waitFor } from '@testing-library/react' import { vi } from 'vitest' -import { ErrorBoundary, Suspense } from '..' -import { ERROR_MESSAGE, FALLBACK, MS_100, TEXT, delay } from '../utils/toTest' +import { ERROR_MESSAGE, FALLBACK, MS_100, TEXT, delay } from './utils/toTest' import { Await, awaitClient, useAwait } from '.' const key = (id: number) => ['key', id] as const diff --git a/packages/react/src/experimental/Await.tsx b/packages/react-await/src/Await.tsx similarity index 98% rename from packages/react/src/experimental/Await.tsx rename to packages/react-await/src/Await.tsx index 949a8a71d..c65a700f3 100644 --- a/packages/react/src/experimental/Await.tsx +++ b/packages/react-await/src/Await.tsx @@ -1,8 +1,8 @@ import type { FunctionComponent } from 'react' import { createElement, useMemo } from 'react' import { useSyncExternalStore } from 'use-sync-external-store/shim' -import type { Tuple } from '../types' -import { hashKey } from '../utils' +import type { Tuple } from './types' +import { hashKey } from './utils' export type Key = Tuple diff --git a/packages/react/src/experimental/index.ts b/packages/react-await/src/index.ts similarity index 100% rename from packages/react/src/experimental/index.ts rename to packages/react-await/src/index.ts diff --git a/packages/react-await/src/types/Tuple.ts b/packages/react-await/src/types/Tuple.ts new file mode 100644 index 000000000..541ceafd9 --- /dev/null +++ b/packages/react-await/src/types/Tuple.ts @@ -0,0 +1 @@ +export type Tuple = T[] | readonly T[] diff --git a/packages/react-await/src/types/index.ts b/packages/react-await/src/types/index.ts new file mode 100644 index 000000000..eed3c4b0a --- /dev/null +++ b/packages/react-await/src/types/index.ts @@ -0,0 +1,2 @@ +export type { PropsWithoutChildren } from './PropsWithoutChildren' +export type { Tuple } from './Tuple' diff --git a/packages/react-await/src/utils/assert.spec.ts b/packages/react-await/src/utils/assert.spec.ts new file mode 100644 index 000000000..f3e0c3fbc --- /dev/null +++ b/packages/react-await/src/utils/assert.spec.ts @@ -0,0 +1,36 @@ +import { expectTypeOf } from 'vitest' +import { assert } from '.' + +function get(type: 'foo' | 'bar') { + switch (type) { + case 'foo': + return { + foo1: 'foo1', + foo2: 'foo2', + } as const + case 'bar': + return { + bar1: 'bar1', + bar2: 'bar2', + } as const + default: { + throw new Error('no type') + } + } +} + +describe('assert', () => { + // eslint-disable-next-line vitest/expect-expect + it('should assert condition', () => { + const data = get('foo') + assert(data.foo1 === 'foo1', 'dummy-message') + expectTypeOf(data.foo2).toMatchTypeOf() + expectTypeOf(data.bar1).not.toMatchTypeOf() + }) + + it('should throw error if given condition is not met', () => { + const assertMessage = "value should be 'paz'" + const value = 'baz' as string + expect(() => assert(value === 'paz', assertMessage)).toThrow(assertMessage) + }) +}) diff --git a/packages/react-await/src/utils/assert.ts b/packages/react-await/src/utils/assert.ts new file mode 100644 index 000000000..ffeecf47e --- /dev/null +++ b/packages/react-await/src/utils/assert.ts @@ -0,0 +1,19 @@ +export function assert(condition: boolean, message: string): asserts condition { + if (!condition) { + throw new Error(message) + } +} + +assert.message = { + useErrorBoundary: { + onlyInChildrenOfErrorBoundary: 'useErrorBoundary: this hook should be called in ErrorBoundary.props.children', + }, + useErrorBoundaryFallbackProps: { + onlyInFallbackOfErrorBoundary: + 'useErrorBoundaryFallbackProps: this hook should be called in ErrorBoundary.props.fallback', + }, + useErrorBoundaryGroup: { + onlyInChildrenOfErrorBoundaryGroup: + 'useErrorBoundaryGroup: this hook should be called in ErrorBoundaryGroup.props.children', + }, +} as const diff --git a/packages/react-await/src/utils/hasResetKeysChanged.spec.ts b/packages/react-await/src/utils/hasResetKeysChanged.spec.ts new file mode 100644 index 000000000..8b1b37eae --- /dev/null +++ b/packages/react-await/src/utils/hasResetKeysChanged.spec.ts @@ -0,0 +1,53 @@ +import { hasResetKeysChanged } from '.' + +const primitive = 0 +const reference1 = { test: 0 } +const reference2 = { test: 0 } + +describe('hasResetKeysChanged', () => { + it('should return true if the two arrays have different lengths.', () => { + const array1 = Array.from({ length: 1 }).map((_, index) => primitive + index) + const array2 = Array.from({ length: 2 }).map((_, index) => primitive + index) + + expect(hasResetKeysChanged(array1, array2)).toBe(true) + }) + + it('should return false if the two arrays have same lengths and same primitive element in each index of arrays.', () => { + const array1 = Array.from({ length: 1 }).map((_, index) => primitive + index) + const array2 = Array.from({ length: 1 }).map((_, index) => primitive + index) + + expect(hasResetKeysChanged(array1, array2)).toBe(false) + }) + + it('should return true if the two arrays have same lengths but at least one primitive element is different in each index of arrays.', () => { + const array1 = [primitive, primitive + 1] + const array2 = [primitive, primitive] + + expect(hasResetKeysChanged(array1, array2)).toBe(true) + }) + + it('should return true if the two arrays have same lengths and have all same primitive elements but order is different', () => { + const array1 = [primitive, primitive + 1] + const array2 = [primitive + 1, primitive] + + expect(hasResetKeysChanged(array1, array2)).toBe(true) + }) + + it('should return true when two arrays have each references elements in index of array have different references', () => { + const array1 = [reference1, { test: 2 }] + const array2 = [reference1, { test: 2 }] + + expect(hasResetKeysChanged(array1, array2)).toBe(true) + }) + + it('should return false when two arrays have each references elements in index of array have same references', () => { + const array1 = [reference1, reference2] + const array2 = [reference1, reference2] + + expect(hasResetKeysChanged(array1, array2)).toBe(false) + }) + + it('should return false when no arrays as parameters. because of default value', () => { + expect(hasResetKeysChanged()).toBe(false) + }) +}) diff --git a/packages/react-await/src/utils/hasResetKeysChanged.ts b/packages/react-await/src/utils/hasResetKeysChanged.ts new file mode 100644 index 000000000..12c1d147f --- /dev/null +++ b/packages/react-await/src/utils/hasResetKeysChanged.ts @@ -0,0 +1,2 @@ +export const hasResetKeysChanged = (a: unknown[] = [], b: unknown[] = []) => + a.length !== b.length || a.some((item, index) => !Object.is(item, b[index])) diff --git a/packages/react-await/src/utils/hashKey.spec.ts b/packages/react-await/src/utils/hashKey.spec.ts new file mode 100644 index 000000000..8f6bf57a2 --- /dev/null +++ b/packages/react-await/src/utils/hashKey.spec.ts @@ -0,0 +1,26 @@ +import { hashKey } from './hashKey' + +const key1 = [ + { + field1: 'field1', + field2: 'field2', + }, +] +const key2 = [ + { + field2: 'field2', + field1: 'field1', + }, +] + +describe('JSON.stringify', () => { + it("should make different string regardless of key's field order", () => { + expect(JSON.stringify(key1) === JSON.stringify(key2)).toBe(false) + }) +}) + +describe('hashKey', () => { + it("should make same string regardless of key's field order", () => { + expect(hashKey(key1) === hashKey(key2)).toBe(true) + }) +}) diff --git a/packages/react-await/src/utils/hashKey.ts b/packages/react-await/src/utils/hashKey.ts new file mode 100644 index 000000000..5b153ad27 --- /dev/null +++ b/packages/react-await/src/utils/hashKey.ts @@ -0,0 +1,15 @@ +import type { Key } from '../Await' +import type { PlainObject } from './isPlainObject' +import { isPlainObject } from './isPlainObject' + +export const hashKey = (key: Key) => + JSON.stringify(key, (_, val) => + isPlainObject(val) + ? Object.keys(val) + .sort() + .reduce((acc: PlainObject, cur) => { + acc[cur] = val[cur] + return acc + }, {}) + : val + ) diff --git a/packages/react-await/src/utils/index.ts b/packages/react-await/src/utils/index.ts new file mode 100644 index 000000000..214d840aa --- /dev/null +++ b/packages/react-await/src/utils/index.ts @@ -0,0 +1,3 @@ +export { hasResetKeysChanged } from './hasResetKeysChanged' +export { hashKey } from './hashKey' +export { assert } from './assert' diff --git a/packages/react-await/src/utils/isPlainObject.spec.ts b/packages/react-await/src/utils/isPlainObject.spec.ts new file mode 100644 index 000000000..dfee6f611 --- /dev/null +++ b/packages/react-await/src/utils/isPlainObject.spec.ts @@ -0,0 +1,44 @@ +import { isPlainObject } from './isPlainObject' + +describe('isPlainObject', () => { + it('should return true for a plain object', () => { + expect(isPlainObject({})).toBe(true) + }) + + it('should return true for an object without a constructor', () => { + expect(isPlainObject(Object.create(null))).toBe(true) + }) + + it('should return false for an array', () => { + expect(isPlainObject([])).toBe(false) + }) + + it('should return false for a null value', () => { + expect(isPlainObject(null)).toBe(false) + }) + + it('should return false for an undefined value', () => { + expect(isPlainObject(undefined)).toBe(false) + }) + + it('should return false for an object instance without an Object-specific method', () => { + class Foo { + abc: any + constructor() { + this.abc = {} + } + } + expect(isPlainObject(new Foo())).toBe(false) + }) + + it('should return false for an object with a custom prototype', () => { + function Graph(this: any) { + this.vertices = [] + this.edges = [] + } + Graph.prototype.addVertex = function (v: any) { + this.vertices.push(v) + } + expect(isPlainObject(Object.create(Graph))).toBe(false) + }) +}) diff --git a/packages/react-await/src/utils/isPlainObject.ts b/packages/react-await/src/utils/isPlainObject.ts new file mode 100644 index 000000000..96f0c5610 --- /dev/null +++ b/packages/react-await/src/utils/isPlainObject.ts @@ -0,0 +1,29 @@ +export type PlainObject = Record + +export const isPlainObject = (value: any): value is PlainObject => { + if (!hasObjectPrototype(value)) { + return false + } + + // If has modified constructor + const ctor = value.constructor + if (typeof ctor === 'undefined') { + return true + } + + // If has modified prototype + const prot = ctor.prototype + if (!hasObjectPrototype(prot)) { + return false + } + + // If constructor does not have an Object-specific method + if (!Object.prototype.hasOwnProperty.call(prot, 'isPrototypeOf')) { + return false + } + + // Most likely a plain Object + return true +} + +const hasObjectPrototype = (value: any) => Object.prototype.toString.call(value) === '[object Object]' diff --git a/packages/react-await/src/utils/toTest.tsx b/packages/react-await/src/utils/toTest.tsx new file mode 100644 index 000000000..a3cb70c02 --- /dev/null +++ b/packages/react-await/src/utils/toTest.tsx @@ -0,0 +1,25 @@ +import type { ReactNode } from 'react' + +const suspendIsNeed = { current: true } +type SuspendProps = { during: number; toShow?: ReactNode } +export const Suspend = ({ during, toShow }: SuspendProps) => { + if (suspendIsNeed.current) { + throw new Promise((resolve) => + setTimeout(() => { + suspendIsNeed.current = false + resolve('resolved') + }, during) + ) + } + return <>{toShow} +} +Suspend.reset = () => { + suspendIsNeed.current = true +} + +export const delay = (ms: number) => new Promise((resolve) => setTimeout(() => resolve('done'), ms)) + +export const TEXT = 'TEXT' as const +export const ERROR_MESSAGE = 'ERROR_MESSAGE' as const +export const FALLBACK = 'FALLBACK' as const +export const MS_100 = 100 as const diff --git a/packages/react-await/test.setup.ts b/packages/react-await/test.setup.ts new file mode 100644 index 000000000..d63189040 --- /dev/null +++ b/packages/react-await/test.setup.ts @@ -0,0 +1,9 @@ +import matchers from '@testing-library/jest-dom/matchers' +import { cleanup } from '@testing-library/react' +import { afterEach, expect } from 'vitest' + +expect.extend(matchers) + +afterEach(() => { + cleanup() +}) diff --git a/packages/react-await/tsconfig.json b/packages/react-await/tsconfig.json new file mode 100644 index 000000000..93a86b8cf --- /dev/null +++ b/packages/react-await/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "@suspensive/tsconfig/react-library.json", + "include": ["."], + "compilerOptions": { + "types": ["node", "@testing-library/jest-dom"] + } +} diff --git a/packages/react-await/tsup.config.ts b/packages/react-await/tsup.config.ts new file mode 100644 index 000000000..9560a461a --- /dev/null +++ b/packages/react-await/tsup.config.ts @@ -0,0 +1,4 @@ +import { options } from '@suspensive/tsup' +import { defineConfig } from 'tsup' + +export default defineConfig(options) diff --git a/packages/react-await/vitest.config.ts b/packages/react-await/vitest.config.ts new file mode 100644 index 000000000..fc20065cc --- /dev/null +++ b/packages/react-await/vitest.config.ts @@ -0,0 +1,4 @@ +import { forPackage } from '@suspensive/vitest' +import { defineConfig } from 'vitest/config' + +export default defineConfig(forPackage()) diff --git a/packages/react-query/package.json b/packages/react-query/package.json index 5ba2a8537..10cb48ef6 100644 --- a/packages/react-query/package.json +++ b/packages/react-query/package.json @@ -49,6 +49,7 @@ "build:watch": "tsup --watch", "clean": "rimraf ./dist && rimraf ./coverage", "lint": "eslint \"**/*.ts*\"", + "lint:attw": "attw --pack", "lint:pub": "publint --strict", "prepack": "pnpm build && pnpm test:tsd", "test": "vitest run --coverage", diff --git a/packages/react/package.json b/packages/react/package.json index da882e277..e92a5466d 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -35,16 +35,6 @@ "default": "./dist/index.cjs" } }, - "./experimental": { - "import": { - "types": "./dist/experimental/index.d.ts", - "default": "./dist/experimental/index.js" - }, - "require": { - "types": "./dist/experimental/index.d.cts", - "default": "./dist/experimental/index.cjs" - } - }, "./package.json": "./package.json" }, "main": "dist/index.cjs", @@ -58,15 +48,13 @@ "build:watch": "tsup --watch", "clean": "rimraf ./dist && rimraf ./coverage", "lint": "eslint \"**/*.ts*\"", + "lint:attw": "attw --pack", "lint:pub": "publint --strict", "prepack": "pnpm build", "test": "vitest run --coverage", "test:watch": "vitest --ui --coverage.enabled=true", "type:check": "tsc --noEmit" }, - "dependencies": { - "use-sync-external-store": "^1.2.0" - }, "devDependencies": { "@suspensive/tsup": "workspace:*", "@suspensive/vitest": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 59d042143..bb625bf35 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,9 @@ importers: .: devDependencies: + '@arethetypeswrong/cli': + specifier: ^0.12.2 + version: 0.12.2 '@changesets/cli': specifier: ^2.26.1 version: 2.26.1 @@ -214,11 +217,41 @@ importers: version: 5.1.6 packages/react: + devDependencies: + '@suspensive/tsup': + specifier: workspace:* + version: link:../../configs/tsup + '@suspensive/vitest': + specifier: workspace:* + version: link:../../configs/vitest + '@types/node': + specifier: ^18.16.2 + version: 18.16.2 + '@types/react': + specifier: ^18.2.0 + version: 18.2.0 + '@types/react-dom': + specifier: ^18.2.1 + version: 18.2.1 + '@types/use-sync-external-store': + specifier: ^0.0.4 + version: 0.0.4 + react: + specifier: ^18.2.0 + version: 18.2.0 + react-dom: + specifier: ^18.2.0 + version: 18.2.0(react@18.2.0) + + packages/react-await: dependencies: use-sync-external-store: specifier: ^1.2.0 version: 1.2.0(react@18.2.0) devDependencies: + '@suspensive/react': + specifier: workspace:* + version: link:../react '@suspensive/tsup': specifier: workspace:* version: link:../../configs/tsup @@ -343,6 +376,39 @@ packages: '@jridgewell/trace-mapping': 0.3.18 dev: true + /@andrewbranch/untar.js@1.0.3: + resolution: {integrity: sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==} + dev: true + + /@arethetypeswrong/cli@0.12.2: + resolution: {integrity: sha512-SE4Rqy8LM8zgRLeVXZqFIOg4w4TCDG2AMguuZDDRcrUmVQj7phW0tWJnKwsZtyJ6SdqXTIzWvGYiUJiHg2hb9w==} + hasBin: true + dependencies: + '@arethetypeswrong/core': 0.12.2 + chalk: 4.1.2 + cli-table3: 0.6.3 + commander: 10.0.1 + marked: 5.1.2 + marked-terminal: 5.2.0(marked@5.1.2) + node-fetch: 2.7.0 + semver: 7.5.4 + transitivePeerDependencies: + - encoding + dev: true + + /@arethetypeswrong/core@0.12.2: + resolution: {integrity: sha512-ez/quGfC6RVg7VrwCgMVreJ01jbkfJQRNxOG7Bpl4YGcPRs45ZE1AzpHiIdzqfwFg9EBVSaewaffrsK5MVbALw==} + dependencies: + '@andrewbranch/untar.js': 1.0.3 + fetch-ponyfill: 7.1.0 + fflate: 0.7.4 + semver: 7.5.4 + typescript: 5.2.2 + validate-npm-package-name: 5.0.0 + transitivePeerDependencies: + - encoding + dev: true + /@babel/code-frame@7.21.4: resolution: {integrity: sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==} engines: {node: '>=6.9.0'} @@ -580,6 +646,13 @@ packages: prettier: 2.8.8 dev: true + /@colors/colors@1.5.0: + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + requiresBuild: true + dev: true + optional: true + /@commitlint/cli@17.6.1: resolution: {integrity: sha512-kCnDD9LE2ySiTnj/VPaxy4/oRayRcdv4aCuVxtoum8SxIU7OADHc0nJPQfheE8bHcs3zZdWzDMWltRosuT13bg==} engines: {node: '>=v14'} @@ -674,7 +747,7 @@ packages: lodash.merge: 4.6.2 lodash.uniq: 4.5.0 resolve-from: 5.0.0 - ts-node: 10.9.1(@types/node@20.0.0)(typescript@5.2.2) + ts-node: 10.9.1(@types/node@20.0.0)(typescript@5.1.6) typescript: 5.2.2 transitivePeerDependencies: - '@swc/core' @@ -2453,6 +2526,13 @@ packages: type-fest: 0.21.3 dev: true + /ansi-escapes@6.2.0: + resolution: {integrity: sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==} + engines: {node: '>=14.16'} + dependencies: + type-fest: 3.13.1 + dev: true + /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -2487,6 +2567,10 @@ packages: engines: {node: '>=12'} dev: true + /ansicolors@0.3.2: + resolution: {integrity: sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==} + dev: true + /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} dev: true @@ -2784,6 +2868,12 @@ packages: engines: {node: '>=6'} dev: false + /builtins@5.0.1: + resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} + dependencies: + semver: 7.5.4 + dev: true + /bundle-name@3.0.0: resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==} engines: {node: '>=12'} @@ -2849,6 +2939,14 @@ packages: /caniuse-lite@1.0.30001489: resolution: {integrity: sha512-x1mgZEXK8jHIfAxm+xgdpHpk50IN3z3q3zP261/WS+uvePxW8izXuCu6AHz0lkuYTlATDehiZ/tNyYBdSQsOUQ==} + /cardinal@2.1.1: + resolution: {integrity: sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==} + hasBin: true + dependencies: + ansicolors: 0.3.2 + redeyed: 2.1.1 + dev: true + /ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} dev: false @@ -2964,6 +3062,15 @@ packages: engines: {node: '>=6'} dev: true + /cli-table3@0.6.3: + resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} + engines: {node: 10.* || >= 12.*} + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + dev: true + /cli-truncate@2.1.0: resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} engines: {node: '>=8'} @@ -3193,7 +3300,7 @@ packages: dependencies: '@types/node': 20.0.0 cosmiconfig: 8.1.3 - ts-node: 10.9.1(@types/node@20.0.0)(typescript@5.2.2) + ts-node: 10.9.1(@types/node@20.0.0)(typescript@5.1.6) typescript: 5.2.2 dev: true @@ -4364,7 +4471,7 @@ packages: minimatch: 3.1.2 object.values: 1.1.6 resolve: 1.22.2 - semver: 6.3.0 + semver: 6.3.1 tsconfig-paths: 3.14.2 transitivePeerDependencies: - eslint-import-resolver-typescript @@ -4449,7 +4556,7 @@ packages: minimatch: 3.1.2 object.entries: 1.1.6 object.fromentries: 2.0.6 - semver: 6.3.0 + semver: 6.3.1 dev: true /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.3.0)(eslint@8.42.0)(prettier@2.8.8): @@ -4837,6 +4944,18 @@ packages: dependencies: reusify: 1.0.4 + /fetch-ponyfill@7.1.0: + resolution: {integrity: sha512-FhbbL55dj/qdVO3YNK7ZEkshvj3eQ7EuIGV2I6ic/2YiocvyWv+7jg2s4AyS0wdRU75s3tA8ZxI/xPigb0v5Aw==} + dependencies: + node-fetch: 2.6.13 + transitivePeerDependencies: + - encoding + dev: true + + /fflate@0.7.4: + resolution: {integrity: sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==} + dev: true + /fflate@0.8.1: resolution: {integrity: sha512-/exOvEuc+/iaUm105QIiOt4LpBdMTWsXxqR0HDF35vx3fmaKzw7354gTilCh5rkzEt8WYyG//ku3h3nRmd7CHQ==} @@ -6496,6 +6615,27 @@ packages: resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} dev: false + /marked-terminal@5.2.0(marked@5.1.2): + resolution: {integrity: sha512-Piv6yNwAQXGFjZSaiNljyNFw7jKDdGrw70FSbtxEyldLsyeuV5ZHm/1wW++kWbrOF1VPnUgYOhB2oLL0ZpnekA==} + engines: {node: '>=14.13.1 || >=16.0.0'} + peerDependencies: + marked: ^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 + dependencies: + ansi-escapes: 6.2.0 + cardinal: 2.1.1 + chalk: 5.2.0 + cli-table3: 0.6.3 + marked: 5.1.2 + node-emoji: 1.11.0 + supports-hyperlinks: 2.3.0 + dev: true + + /marked@5.1.2: + resolution: {integrity: sha512-ahRPGXJpjMjwSOlBoTMZAK7ATXkli5qCPxZ21TG44rx1KEo44bii4ekgTDQPNRQ4Kh7JMb9Ub1PVk1NxRSsorg==} + engines: {node: '>= 16'} + hasBin: true + dev: true + /match-sorter@6.3.1: resolution: {integrity: sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==} dependencies: @@ -7488,6 +7628,36 @@ packages: - supports-color dev: false + /node-emoji@1.11.0: + resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} + dependencies: + lodash: 4.17.21 + dev: true + + /node-fetch@2.6.13: + resolution: {integrity: sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: true + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: true + /node-releases@2.0.12: resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==} dev: true @@ -8218,6 +8388,12 @@ packages: strip-indent: 3.0.0 dev: true + /redeyed@2.1.1: + resolution: {integrity: sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==} + dependencies: + esprima: 4.0.1 + dev: true + /reflect.getprototypeof@1.0.4: resolution: {integrity: sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==} engines: {node: '>= 0.4'} @@ -9182,6 +9358,10 @@ packages: universalify: 0.2.0 url-parse: 1.5.10 + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: true + /tr46@1.0.1: resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} dependencies: @@ -9261,37 +9441,6 @@ packages: yn: 3.1.1 dev: true - /ts-node@10.9.1(@types/node@20.0.0)(typescript@5.2.2): - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.9 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.0.0 - acorn: 8.8.2 - acorn-walk: 8.2.0 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.2.2 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - dev: true - /ts-toolbelt@6.15.5: resolution: {integrity: sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==} dev: true @@ -9501,6 +9650,11 @@ packages: engines: {node: '>=10'} dev: false + /type-fest@3.13.1: + resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} + engines: {node: '>=14.16'} + dev: true + /typed-array-buffer@1.0.0: resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} engines: {node: '>= 0.4'} @@ -9777,6 +9931,13 @@ packages: spdx-expression-parse: 3.0.1 dev: true + /validate-npm-package-name@5.0.0: + resolution: {integrity: sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dependencies: + builtins: 5.0.1 + dev: true + /vfile-location@5.0.2: resolution: {integrity: sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==} dependencies: @@ -9981,6 +10142,10 @@ packages: resolution: {integrity: sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==} dev: false + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: true + /webidl-conversions@4.0.2: resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} dev: true @@ -10006,6 +10171,13 @@ packages: tr46: 4.1.1 webidl-conversions: 7.0.0 + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: true + /whatwg-url@7.1.0: resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} dependencies: diff --git a/turbo.json b/turbo.json index 59e0457ac..186e5466b 100644 --- a/turbo.json +++ b/turbo.json @@ -5,6 +5,7 @@ "build:watch": { "outputs": ["dist/**"] }, "npm:publish": { "dependsOn": ["^build"] }, "lint": { "cache": false }, + "lint:attw": { "dependsOn": ["^build"], "cache": false }, "lint:pub": { "cache": false }, "test": { "outputs": ["coverage/**"], "cache": false }, "test:tsd": {},