From 7c6c3b1d79bf93f4ba9702b75a5ffa2f67ab7531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=84=9D=EC=A7=84=28poki=29?= <102217654+SEOKKAMONI@users.noreply.github.com> Date: Sun, 29 Sep 2024 19:12:02 +0900 Subject: [PATCH] chore: remove cache pacakge (#1279) # Overview - remove cache pacakge > Creating a library for caching turned out to be a much more challenging task than we initially expected, as it felt like creating something from nothing. After extensive discussions and considering our limited resources and the complexity of the project, we have decided to conclude the work at this point and discontinue further development. ## PR Checklist - [x] I did below actions if need 1. I read the [Contributing Guide](https://github.com/toss/suspensive/blob/main/CONTRIBUTING.md) 2. I added documents and tests. --------- Co-authored-by: Jonghyeon Ko --- .github/ISSUE_TEMPLATE/bug.yml | 1 - .github/ISSUE_TEMPLATE/feature_request.yml | 1 - .github/labeler.yml | 2 - README.md | 6 - codecov.yml | 4 - .../src/pages/docs/changelogs.en.mdx | 1 - .../src/pages/docs/changelogs.ko.mdx | 1 - examples/visualization/package.json | 1 - .../src/app/cache/SuspenseCache/page.tsx | 38 ---- examples/visualization/src/app/providers.tsx | 16 +- packages/cache/CHANGELOG.md | 195 ------------------ packages/cache/LICENSE | 21 -- packages/cache/README.ko.md | 13 -- packages/cache/README.md | 13 -- packages/cache/eslint.config.mjs | 15 -- packages/cache/package.json | 69 ------- packages/cache/src/Cache.ts | 195 ------------------ packages/cache/src/CacheProvider.tsx | 12 -- packages/cache/src/CacheStore.spec.tsx | 166 --------------- packages/cache/src/Read.spec.tsx | 33 --- packages/cache/src/Read.tsx | 17 -- packages/cache/src/cacheOptions.spec.tsx | 49 ----- packages/cache/src/cacheOptions.test-d.tsx | 38 ---- packages/cache/src/cacheOptions.ts | 17 -- packages/cache/src/contexts/CacheContext.ts | 4 - packages/cache/src/contexts/index.ts | 1 - packages/cache/src/index.ts | 6 - packages/cache/src/models/Subscribable.ts | 19 -- packages/cache/src/types.ts | 16 -- packages/cache/src/useCache.ts | 14 -- packages/cache/src/useRead.spec.tsx | 125 ----------- packages/cache/src/useRead.ts | 18 -- .../cache/src/utility-types/ExtractPartial.ts | 4 - packages/cache/src/utility-types/Tuple.ts | 1 - packages/cache/src/utility-types/index.ts | 1 - packages/cache/src/utils/hashCacheKey.spec.ts | 26 --- packages/cache/src/utils/hashCacheKey.ts | 14 -- packages/cache/src/utils/index.ts | 1 - .../cache/src/utils/isPlainObject.spec.ts | 48 ----- packages/cache/src/utils/isPlainObject.ts | 29 --- packages/cache/tsconfig.json | 7 - packages/cache/tsup.config.ts | 4 - packages/cache/vitest.config.ts | 15 -- packages/cache/vitest.setup.ts | 7 - pnpm-lock.yaml | 28 --- 45 files changed, 6 insertions(+), 1306 deletions(-) delete mode 100644 examples/visualization/src/app/cache/SuspenseCache/page.tsx delete mode 100644 packages/cache/CHANGELOG.md delete mode 100644 packages/cache/LICENSE delete mode 100644 packages/cache/README.ko.md delete mode 100644 packages/cache/README.md delete mode 100644 packages/cache/eslint.config.mjs delete mode 100644 packages/cache/package.json delete mode 100644 packages/cache/src/Cache.ts delete mode 100644 packages/cache/src/CacheProvider.tsx delete mode 100644 packages/cache/src/CacheStore.spec.tsx delete mode 100644 packages/cache/src/Read.spec.tsx delete mode 100644 packages/cache/src/Read.tsx delete mode 100644 packages/cache/src/cacheOptions.spec.tsx delete mode 100644 packages/cache/src/cacheOptions.test-d.tsx delete mode 100644 packages/cache/src/cacheOptions.ts delete mode 100644 packages/cache/src/contexts/CacheContext.ts delete mode 100644 packages/cache/src/contexts/index.ts delete mode 100644 packages/cache/src/index.ts delete mode 100644 packages/cache/src/models/Subscribable.ts delete mode 100644 packages/cache/src/types.ts delete mode 100644 packages/cache/src/useCache.ts delete mode 100644 packages/cache/src/useRead.spec.tsx delete mode 100644 packages/cache/src/useRead.ts delete mode 100644 packages/cache/src/utility-types/ExtractPartial.ts delete mode 100644 packages/cache/src/utility-types/Tuple.ts delete mode 100644 packages/cache/src/utility-types/index.ts delete mode 100644 packages/cache/src/utils/hashCacheKey.spec.ts delete mode 100644 packages/cache/src/utils/hashCacheKey.ts delete mode 100644 packages/cache/src/utils/index.ts delete mode 100644 packages/cache/src/utils/isPlainObject.spec.ts delete mode 100644 packages/cache/src/utils/isPlainObject.ts delete mode 100644 packages/cache/tsconfig.json delete mode 100644 packages/cache/tsup.config.ts delete mode 100644 packages/cache/vitest.config.ts delete mode 100644 packages/cache/vitest.setup.ts diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 9e2d9bae2..24092f509 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -19,7 +19,6 @@ body: - "@suspensive/react-query-next-experimental" - "@suspensive/react-query-next-experimental-4" - "@suspensive/jotai" - - "@suspensive/cache" - "@suspensive/react-image" - etc validations: diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index c93cc78d0..2412c08ef 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -19,7 +19,6 @@ body: - "@suspensive/react-query-next-experimental" - "@suspensive/react-query-next-experimental-4" - "@suspensive/jotai" - - "@suspensive/cache" - "@suspensive/react-image" - etc validations: diff --git a/.github/labeler.yml b/.github/labeler.yml index 7689cfd82..cc46d8266 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -18,8 +18,6 @@ - "packages/react-query-next-experimental-4/**/*" "@suspensive/jotai": - "packages/jotai/**/*" -"@suspensive/cache": - - "packages/cache/**/*" "@suspensive/react-image": - "packages/react-image/**/*" "suspensive.org": diff --git a/README.md b/README.md index d6af5e4ef..376c71dee 100644 --- a/README.md +++ b/README.md @@ -34,12 +34,6 @@ Key features: useSuspenseQuery, useSuspenseQueries, useSuspenseInfiniteQuery, qu Key features: Atom, AtomValue, SetAtom, and more. -### @suspensive/cache [![npm version](https://img.shields.io/npm/v/@suspensive/cache?color=000&labelColor=000&logo=npm&label=)](https://www.npmjs.com/package/@suspensive/cache) [![npm](https://img.shields.io/npm/dm/@suspensive/cache?color=000&labelColor=000)](https://www.npmjs.com/package/@suspensive/cache) [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@suspensive/cache?color=000&labelColor=000)](https://www.npmjs.com/package/@suspensive/cache) - -> This package provides caching solutions that can be used within React applications. It includes hooks like useRead and useCache, as well as providers for managing and storing cache data efficiently. - -Key features: Read, useRead, Cache, useCache, CacheProvider, and more. -
## Visit [suspensive.org](https://suspensive.org) for docs, guides, API and more! diff --git a/codecov.yml b/codecov.yml index 59de62600..621c00078 100644 --- a/codecov.yml +++ b/codecov.yml @@ -60,10 +60,6 @@ component_management: name: '@suspensive/jotai' paths: - packages/jotai/** - - component_id: cache - name: '@suspensive/cache' - paths: - - packages/cache/** - component_id: react-image name: '@suspensive/react-image' paths: diff --git a/docs/suspensive.org/src/pages/docs/changelogs.en.mdx b/docs/suspensive.org/src/pages/docs/changelogs.en.mdx index ce2530055..2faa7367b 100644 --- a/docs/suspensive.org/src/pages/docs/changelogs.en.mdx +++ b/docs/suspensive.org/src/pages/docs/changelogs.en.mdx @@ -13,5 +13,4 @@ import { Cards, Card } from 'nextra/components' href="https://github.com/toss/suspensive/blob/main/packages/react-image/CHANGELOG.md" /> - diff --git a/docs/suspensive.org/src/pages/docs/changelogs.ko.mdx b/docs/suspensive.org/src/pages/docs/changelogs.ko.mdx index ce2530055..2faa7367b 100644 --- a/docs/suspensive.org/src/pages/docs/changelogs.ko.mdx +++ b/docs/suspensive.org/src/pages/docs/changelogs.ko.mdx @@ -13,5 +13,4 @@ import { Cards, Card } from 'nextra/components' href="https://github.com/toss/suspensive/blob/main/packages/react-image/CHANGELOG.md" /> - diff --git a/examples/visualization/package.json b/examples/visualization/package.json index 7f1f94f80..baeb13a82 100644 --- a/examples/visualization/package.json +++ b/examples/visualization/package.json @@ -12,7 +12,6 @@ "start": "next start -p 4001" }, "dependencies": { - "@suspensive/cache": "workspace:*", "@suspensive/react": "workspace:*", "@suspensive/react-dom": "workspace:*", "@suspensive/react-image": "workspace:*", diff --git a/examples/visualization/src/app/cache/SuspenseCache/page.tsx b/examples/visualization/src/app/cache/SuspenseCache/page.tsx deleted file mode 100644 index 6098d4da2..000000000 --- a/examples/visualization/src/app/cache/SuspenseCache/page.tsx +++ /dev/null @@ -1,38 +0,0 @@ -'use client' - -import { Read, cacheOptions, useCache } from '@suspensive/cache' -import { ErrorBoundary, Suspense } from '@suspensive/react' -import { api } from '~/utils' - -const successCache = (ms: number) => - cacheOptions({ - cacheKey: [ms] as const, - cacheFn: () => api.delay(ms, { percentage: 100 }), - }) - -export default function Page() { - const cache = useCache() - - return ( -
error
}> -
- loading...
}> - - {(cached) => ( -
- -
{cached.data}
-
- )} -
- - -
- ) -} diff --git a/examples/visualization/src/app/providers.tsx b/examples/visualization/src/app/providers.tsx index d55ec0459..29ce27f20 100644 --- a/examples/visualization/src/app/providers.tsx +++ b/examples/visualization/src/app/providers.tsx @@ -1,6 +1,5 @@ 'use client' -import { Cache, CacheProvider } from '@suspensive/cache' import { DefaultProps, DefaultPropsProvider } from '@suspensive/react' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { ReactQueryDevtools } from '@tanstack/react-query-devtools' @@ -8,18 +7,15 @@ import { type PropsWithChildren, useState } from 'react' import { Spinner } from '~/components/uis' export const Providers = ({ children }: PropsWithChildren) => { - const cache = useState(() => new Cache())[0] const queryClient = useState(() => new QueryClient({ defaultOptions: { queries: { retry: 0 } } }))[0] const defaultProps = useState(() => new DefaultProps({ Delay: { ms: 1200 }, Suspense: { fallback: } }))[0] return ( - - - - {children} - - - - + + + {children} + + + ) } diff --git a/packages/cache/CHANGELOG.md b/packages/cache/CHANGELOG.md deleted file mode 100644 index 3c7b9ae6c..000000000 --- a/packages/cache/CHANGELOG.md +++ /dev/null @@ -1,195 +0,0 @@ -# @suspensive/cache - -## 0.5.7 - -### Patch Changes - -- [#1272](https://github.com/toss/suspensive/pull/1272) [`89f5b5c`](https://github.com/toss/suspensive/commit/89f5b5c4d9b16bcbed77ef3e17bb1f34babe2921) Thanks [@love1ace](https://github.com/love1ace)! - docs(\*): update description of package.json - -- Updated dependencies [[`89f5b5c`](https://github.com/toss/suspensive/commit/89f5b5c4d9b16bcbed77ef3e17bb1f34babe2921)]: - - @suspensive/utils@2.17.1 - -## 0.5.6 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.17.0 - -## 0.5.5 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.16.1 - -## 0.5.4 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.16.0 - -## 0.5.3 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.15.0 - -## 0.5.2 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.14.2 - -## 0.5.1 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.14.1 - -## 0.5.0 - -### Minor Changes - -- [#1224](https://github.com/toss/suspensive/pull/1224) [`c077fc5`](https://github.com/toss/suspensive/commit/c077fc53ec1e380e238cc722eb1865b1812a2db8) Thanks [@SEOKKAMONI](https://github.com/SEOKKAMONI)! - fix(cache): rename the cache interface name - -## 0.4.1 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.14.0 - -## 0.4.0 - -### Minor Changes - -- [#1197](https://github.com/toss/suspensive/pull/1197) [`0bb493c`](https://github.com/toss/suspensive/commit/0bb493cd34300dc747abd6c138895de8d720160b) Thanks [@SEOKKAMONI](https://github.com/SEOKKAMONI)! - feat(cache): add `Subscribable` - -## 0.3.8 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.13.1 - -## 0.3.7 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.13.0 - -## 0.3.6 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.12.3 - -## 0.3.5 - -### Patch Changes - -- [#1189](https://github.com/toss/suspensive/pull/1189) [`af75cbf`](https://github.com/toss/suspensive/commit/af75cbf0d6f848a1f07099731d50d3904df2facc) Thanks [@SEOKKAMONI](https://github.com/SEOKKAMONI)! - fix(cache): remove unsubscribe method of CacheStore - -## 0.3.4 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.12.2 - -## 0.3.3 - -### Patch Changes - -- [#1180](https://github.com/toss/suspensive/pull/1180) [`f79b96c`](https://github.com/toss/suspensive/commit/f79b96c728e15ebe819445cf5d1c2e33e6c96ef4) Thanks [@manudeli](https://github.com/manudeli)! - fix(\*): remove unnecessary devDeps(react-dom, @types/react-dom) - -- Updated dependencies []: - - @suspensive/utils@2.12.1 - -## 0.3.2 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.12.0 - -## 0.3.1 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.11.0 - -## 0.3.0 - -### Minor Changes - -- [#1140](https://github.com/toss/suspensive/pull/1140) [`eb5d257`](https://github.com/toss/suspensive/commit/eb5d25767013ce1125b17948028c48fb15507037) Thanks [@SEOKKAMONI](https://github.com/SEOKKAMONI)! - feat(cache): add `remove` method to CacheStore - -## 0.2.7 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.10.0 - -## 0.2.6 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.9.4 - -## 0.2.5 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.9.3 - -## 0.2.4 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.9.2 - -## 0.2.3 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.9.1 - -## 0.2.2 - -### Patch Changes - -- Updated dependencies []: - - @suspensive/utils@2.9.0 - -## 0.2.1 - -### Patch Changes - -- Updated dependencies [[`2326b13`](https://github.com/toss/suspensive/commit/2326b1341f167454a889953fb0bbf58449e1ca98)]: - - @suspensive/utils@2.8.1 - -## 0.2.0 - -### Minor Changes - -- [#1089](https://github.com/toss/suspensive/pull/1089) [`be21828`](https://github.com/toss/suspensive/commit/be218284dc67ccc84ffc29a0bfd84c578c1f37f1) Thanks [@SEOKKAMONI](https://github.com/SEOKKAMONI)! - feat(cache): add DataTag feature of cacheOptions - -## 0.1.0 - -### Minor Changes - -- [#1083](https://github.com/toss/suspensive/pull/1083) [`a7c5c58`](https://github.com/toss/suspensive/commit/a7c5c58521ab1aac93420c0a896683917c741af5) Thanks [@SEOKKAMONI](https://github.com/SEOKKAMONI)! - feat(cache): add CacheStore, useCacheStore, CacheStoreProvider, useCache, Cache, cacheOptions diff --git a/packages/cache/LICENSE b/packages/cache/LICENSE deleted file mode 100644 index 69dc6a701..000000000 --- a/packages/cache/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Viva Republica, Inc. - -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/cache/README.ko.md b/packages/cache/README.ko.md deleted file mode 100644 index 963bb1839..000000000 --- a/packages/cache/README.ko.md +++ /dev/null @@ -1,13 +0,0 @@ -# 라이브러리 소개 - -[![npm version](https://img.shields.io/npm/v/@suspensive/cache?color=000&labelColor=000&logo=npm&label=)](https://www.npmjs.com/package/@suspensive/cache) -[![npm](https://img.shields.io/npm/dm/@suspensive/cache?color=000&labelColor=000)](https://www.npmjs.com/package/@suspensive/cache) -[![npm bundle size](https://img.shields.io/bundlephobia/minzip/@suspensive/cache?color=000&labelColor=000)](https://www.npmjs.com/package/@suspensive/cache) - -## 설치하기 - -@suspensive/cache 는 npm에 있습니다. 최신 안정버전을 설치하기 위해 아래 커맨드를 실행하세요 - -```shell npm2yarn -npm install @suspensive/cache -``` diff --git a/packages/cache/README.md b/packages/cache/README.md deleted file mode 100644 index 9c3ebc2d9..000000000 --- a/packages/cache/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Introduction - -[![npm version](https://img.shields.io/npm/v/@suspensive/cache?color=000&labelColor=000&logo=npm&label=)](https://www.npmjs.com/package/@suspensive/cache) -[![npm](https://img.shields.io/npm/dm/@suspensive/cache?color=000&labelColor=000)](https://www.npmjs.com/package/@suspensive/cache) -[![npm bundle size](https://img.shields.io/bundlephobia/minzip/@suspensive/cache?color=000&labelColor=000)](https://www.npmjs.com/package/@suspensive/cache) - -## Installation - -@suspensive/cache lives in npm. To install the latest stable version, run the following command - -```shell npm2yarn -npm install @suspensive/cache -``` diff --git a/packages/cache/eslint.config.mjs b/packages/cache/eslint.config.mjs deleted file mode 100644 index 0daa8aa5b..000000000 --- a/packages/cache/eslint.config.mjs +++ /dev/null @@ -1,15 +0,0 @@ -import path from 'path' -import { fileURLToPath } from 'url' -import { suspensiveReactTypeScriptConfig } from '@suspensive/eslint-config' - -export default [ - ...suspensiveReactTypeScriptConfig, - { - languageOptions: { - parserOptions: { - tsconfigRootDir: path.dirname(fileURLToPath(import.meta.url)), - project: './tsconfig.json', - }, - }, - }, -] diff --git a/packages/cache/package.json b/packages/cache/package.json deleted file mode 100644 index 8b11454a4..000000000 --- a/packages/cache/package.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "@suspensive/cache", - "version": "0.5.7", - "description": "Suspensive interfaces for caching", - "keywords": [ - "suspensive", - "react", - "cache" - ], - "homepage": "https://suspensive.org", - "bugs": "https://github.com/toss/suspensive/issues", - "repository": { - "type": "git", - "url": "git+https://github.com/toss/suspensive.git", - "directory": "packages/cache" - }, - "license": "MIT", - "author": "Jonghyeon Ko & Seokjin Kim ", - "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", - "module": "dist/index.js", - "types": "dist/index.d.ts", - "files": [ - "dist", - "src" - ], - "scripts": { - "build": "tsup", - "ci:attw": "attw --pack", - "ci:eslint": "eslint \"**/*.{js,jsx,cjs,mjs,ts,tsx,cts,mts}\"", - "ci:publint": "publint --strict", - "ci:test": "vitest run --coverage --typecheck", - "ci:type": "tsc --noEmit", - "clean": "rimraf ./dist && rimraf ./coverage", - "prepack": "pnpm build", - "test:ui": "vitest --ui --coverage --typecheck" - }, - "dependencies": { - "@suspensive/utils": "workspace:*" - }, - "devDependencies": { - "@suspensive/eslint-config": "workspace:*", - "@suspensive/react": "workspace:*", - "@suspensive/tsconfig": "workspace:*", - "@suspensive/tsup": "workspace:*", - "@types/react": "catalog:react18", - "react": "catalog:react18" - }, - "peerDependencies": { - "react": "^18" - }, - "publishConfig": { - "access": "public" - } -} diff --git a/packages/cache/src/Cache.ts b/packages/cache/src/Cache.ts deleted file mode 100644 index 874281d38..000000000 --- a/packages/cache/src/Cache.ts +++ /dev/null @@ -1,195 +0,0 @@ -import { Subscribable } from './models/Subscribable' -import type { CacheKey, CacheOptions } from './types' -import type { ExtractPartial } from './utility-types/ExtractPartial' -import { hashCacheKey } from './utils' - -const enum CacheStatus { - Idle = 'idle', - Pending = 'pending', - Resolved = 'resolved', - Rejected = 'rejected', -} - -export type AllStatusCached = - | { - status: CacheStatus.Idle - promiseToSuspend: undefined - cacheKey: TCacheKey - hashedCacheKey: ReturnType - state: { - promise: undefined - data: undefined - error: undefined - } - } - | { - status: CacheStatus.Pending - promiseToSuspend: Promise - cacheKey: TCacheKey - hashedCacheKey: ReturnType - state: { - promise: Promise - data: undefined - error: undefined - } - } - | { - status: CacheStatus.Resolved - promiseToSuspend: Promise - cacheKey: TCacheKey - hashedCacheKey: ReturnType - state: { - promise: Promise - data: TData - error: undefined - } - } - | { - status: CacheStatus.Rejected - promiseToSuspend: Promise - cacheKey: TCacheKey - hashedCacheKey: ReturnType - state: { - promise: Promise - data: undefined - error: unknown - } - } - -export type IdleCached = ExtractPartial< - AllStatusCached, - { status: CacheStatus.Idle } -> -export type PendingCached = ExtractPartial< - AllStatusCached, - { status: CacheStatus.Pending } -> -export type ResolvedCached = ExtractPartial< - AllStatusCached, - { status: CacheStatus.Resolved } -> -export type RejectedCached = ExtractPartial< - AllStatusCached, - { status: CacheStatus.Rejected } -> - -export type Cached = - | IdleCached - | PendingCached - | ResolvedCached - | RejectedCached - -/** - * @experimental This is experimental feature. - */ -export class Cache extends Subscribable<() => void> { - private cache = new Map, Cached>() - - public reset = (options?: Pick, 'cacheKey'>) => { - if (typeof options?.cacheKey === 'undefined' || options.cacheKey.length === 0) { - this.cache.clear() - this.notify() - return - } - - const hashedCacheKey = hashCacheKey(options.cacheKey) - - if (this.cache.has(hashedCacheKey)) { - this.cache.delete(hashedCacheKey) - } - - this.notify() - } - - public remove = (options: Pick, 'cacheKey'>) => { - const hashedCacheKey = hashCacheKey(options.cacheKey) - - if (this.cache.has(hashedCacheKey)) { - this.cache.delete(hashedCacheKey) - } - } - - public clearError = (options?: Pick, 'cacheKey'>) => { - if (options?.cacheKey === undefined || options.cacheKey.length === 0) { - this.cache.forEach((cached, hashedCacheKey, cache) => { - cache.set(hashedCacheKey, { - ...cached, - status: CacheStatus.Idle, - promiseToSuspend: undefined, - state: { - promise: undefined, - error: undefined, - data: undefined, - }, - }) - }) - return - } - - const hashedCacheKey = hashCacheKey(options.cacheKey) - const cached = this.cache.get(hashedCacheKey) - if (cached) { - this.cache.set(hashedCacheKey, { - ...cached, - status: CacheStatus.Idle, - promiseToSuspend: undefined, - state: { - promise: undefined, - error: undefined, - data: undefined, - }, - }) - } - } - - public suspend = ({ - cacheKey, - cacheFn, - }: CacheOptions): ResolvedCached => { - const hashedCacheKey = hashCacheKey(cacheKey) - const cached = this.cache.get(hashedCacheKey) - if (cached && cached.status !== CacheStatus.Idle) { - if (cached.status === CacheStatus.Rejected) { - throw cached.state.error - } - if (cached.status === CacheStatus.Resolved) { - return cached as ResolvedCached - } - // eslint-disable-next-line @typescript-eslint/only-throw-error - throw cached.promiseToSuspend - } - - const promise = cacheFn({ cacheKey }) - const newCached: Cached = { - cacheKey, - hashedCacheKey, - status: CacheStatus.Pending, - state: { - promise, - data: undefined, - error: undefined, - }, - promiseToSuspend: promise.then( - (data) => { - newCached.status = CacheStatus.Resolved - newCached.state.data = data - newCached.state.error = undefined - }, - (error: unknown) => { - newCached.status = CacheStatus.Rejected - newCached.state.data = undefined - newCached.state.error = error - } - ), - } - - this.cache.set(hashedCacheKey, newCached) - // eslint-disable-next-line @typescript-eslint/only-throw-error - throw newCached.promiseToSuspend - } - - public getData = (options: Pick, 'cacheKey'>) => - this.cache.get(hashCacheKey(options.cacheKey))?.state.data - public getError = (options: Pick, 'cacheKey'>) => - this.cache.get(hashCacheKey(options.cacheKey))?.state.error -} diff --git a/packages/cache/src/CacheProvider.tsx b/packages/cache/src/CacheProvider.tsx deleted file mode 100644 index b71601d8e..000000000 --- a/packages/cache/src/CacheProvider.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { type PropsWithChildren } from 'react' -import type { Cache } from './Cache' -import { CacheContext } from './contexts' - -type CacheProviderProps = PropsWithChildren<{ cache: Cache }> - -/** - * @experimental This is experimental feature. - */ -export function CacheProvider({ cache, children }: CacheProviderProps) { - return {children} -} diff --git a/packages/cache/src/CacheStore.spec.tsx b/packages/cache/src/CacheStore.spec.tsx deleted file mode 100644 index 3409a1d62..000000000 --- a/packages/cache/src/CacheStore.spec.tsx +++ /dev/null @@ -1,166 +0,0 @@ -import { ERROR_MESSAGE, FALLBACK, TEXT, sleep } from '@suspensive/utils' -import { render, screen, waitFor } from '@testing-library/react' -import ms from 'ms' -import { Suspense } from 'react' -import { Cache } from './Cache' -import { cacheOptions } from './cacheOptions' -import { CacheProvider } from './CacheProvider' -import { Read } from './Read' - -const errorCache = (id: number) => - cacheOptions({ - cacheKey: ['key', id] as const, - // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors - cacheFn: () => sleep(ms('0.1s')).then(() => Promise.reject(ERROR_MESSAGE)), - }) - -const successCache = (id: number) => - cacheOptions({ - cacheKey: ['key', id] as const, - cacheFn: () => sleep(ms('0.1s')).then(() => Promise.resolve(TEXT)), - }) - -describe('Cache', () => { - let cache: Cache - - beforeEach(() => { - cache = new Cache() - cache.reset() - }) - - describe('clearError', () => { - it('should clear promise & error for all cached', async () => { - expect(cache.getError(errorCache(1))).toBeUndefined() - expect(cache.getError(errorCache(2))).toBeUndefined() - try { - cache.suspend(errorCache(1)) - } catch (promiseToSuspense) { - await promiseToSuspense - } - try { - cache.suspend(errorCache(2)) - } catch (promiseToSuspense) { - await promiseToSuspense - } - expect(cache.getError(errorCache(1))).toBe(ERROR_MESSAGE) - expect(cache.getError(errorCache(2))).toBe(ERROR_MESSAGE) - - cache.clearError() - expect(cache.getError(errorCache(1))).toBeUndefined() - expect(cache.getError(errorCache(2))).toBeUndefined() - }) - - it('should clear promise & error for specific cached', async () => { - expect(cache.getError(errorCache(1))).toBeUndefined() - expect(cache.getError(errorCache(2))).toBeUndefined() - try { - cache.suspend(errorCache(1)) - } catch (promiseToSuspense) { - expect(await promiseToSuspense).toBeUndefined() - } - try { - cache.suspend(errorCache(1)) - } catch (error) { - expect(error).toBe(ERROR_MESSAGE) - } - try { - cache.suspend(errorCache(2)) - } catch (promiseToSuspense) { - expect(await promiseToSuspense).toBeUndefined() - } - try { - cache.suspend(errorCache(2)) - } catch (error) { - expect(error).toBe(ERROR_MESSAGE) - } - expect(cache.getError(errorCache(1))).toBe(ERROR_MESSAGE) - expect(cache.getError(errorCache(2))).toBe(ERROR_MESSAGE) - - cache.clearError(errorCache(1)) - expect(cache.getError(errorCache(1))).toBeUndefined() - expect(cache.getError(errorCache(2))).toBe(ERROR_MESSAGE) - cache.clearError(errorCache(2)) - expect(cache.getError(errorCache(1))).toBeUndefined() - expect(cache.getError(errorCache(2))).toBeUndefined() - }) - }) - - describe('remove', () => { - it('should remove specific cached', async () => { - try { - cache.suspend(successCache(1)) - } catch (promiseToSuspense) { - await promiseToSuspense - } - expect(cache.getData(successCache(1))).toBe(TEXT) - expect(() => { - cache.remove(successCache(1)) - }).not.throw() - expect(cache.getData(successCache(1))).toBeUndefined() - }) - }) - - describe('reset', () => { - it('should delete all cached and notify to subscribers', async () => { - const mockListener1 = vitest.fn() - const mockListener2 = vitest.fn() - cache.subscribe(mockListener1) - cache.subscribe(mockListener2) - try { - cache.suspend(successCache(1)) - } catch (promiseToSuspense) { - await promiseToSuspense - } - try { - cache.suspend(successCache(2)) - } catch (promiseToSuspense) { - await promiseToSuspense - } - expect(cache.getData(successCache(1))).toBe(TEXT) - expect(cache.getData(successCache(2))).toBe(TEXT) - expect(mockListener1).not.toHaveBeenCalled() - expect(mockListener2).not.toHaveBeenCalled() - cache.reset() - expect(cache.getData(successCache(1))).toBeUndefined() - expect(cache.getData(successCache(2))).toBeUndefined() - expect(mockListener1).toHaveBeenCalledOnce() - expect(mockListener2).toHaveBeenCalledOnce() - }) - - it('should delete specific cached and notify to subscriber', async () => { - const mockListener = vitest.fn() - cache.subscribe(mockListener) - try { - cache.suspend(successCache(1)) - } catch (promiseToSuspense) { - await promiseToSuspense - } - expect(cache.getData(successCache(1))).toBe(TEXT) - expect(mockListener).not.toHaveBeenCalled() - cache.reset(successCache(1)) - expect(cache.getData(successCache(1))).toBeUndefined() - expect(mockListener).toHaveBeenCalledOnce() - }) - }) - - describe('getData', () => { - it('should get data of specific cached', async () => { - render( - - - sleep(ms('0.1s')).then(() => TEXT)}> - {(cached) => <>{cached.data}} - - - - ) - - expect(screen.queryByText(FALLBACK)).toBeInTheDocument() - expect(screen.queryByText(TEXT)).not.toBeInTheDocument() - expect(cache.getData(errorCache(1))).toBeUndefined() - await waitFor(() => expect(screen.queryByText(TEXT)).toBeInTheDocument()) - expect(screen.queryByText(FALLBACK)).not.toBeInTheDocument() - expect(cache.getData(errorCache(1))).toBe(TEXT) - }) - }) -}) diff --git a/packages/cache/src/Read.spec.tsx b/packages/cache/src/Read.spec.tsx deleted file mode 100644 index f81f8256a..000000000 --- a/packages/cache/src/Read.spec.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { Suspense } from '@suspensive/react' -import { TEXT } from '@suspensive/utils' -import { render, screen } from '@testing-library/react' -import { Cache } from './Cache' -import { cacheOptions } from './cacheOptions' -import { CacheProvider } from './CacheProvider' -import { Read } from './Read' - -const successCache = (id: number) => - cacheOptions({ - cacheKey: ['key', id] as const, - cacheFn: () => Promise.resolve(TEXT), - }) - -describe('', () => { - let cache: Cache - - beforeEach(() => { - cache = new Cache() - }) - - it('should render child component with data from useRead hook', async () => { - render( - - - {(cached) => <>{cached.data}} - - - ) - - expect(await screen.findByText(TEXT)).toBeInTheDocument() - }) -}) diff --git a/packages/cache/src/Read.tsx b/packages/cache/src/Read.tsx deleted file mode 100644 index 783a63150..000000000 --- a/packages/cache/src/Read.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import type { ResolvedCached } from './Cache' -import type { CacheKey, CacheOptions } from './types' -import { useRead } from './useRead' - -/** - * @experimental This is experimental feature. - */ -export interface ReadProps extends CacheOptions { - children: (props: ResolvedCached['state']) => JSX.Element -} - -/** - * @experimental This is experimental feature. - */ -export function Read({ children, ...options }: ReadProps) { - return <>{children(useRead(options))} -} diff --git a/packages/cache/src/cacheOptions.spec.tsx b/packages/cache/src/cacheOptions.spec.tsx deleted file mode 100644 index b47f93f57..000000000 --- a/packages/cache/src/cacheOptions.spec.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import { FALLBACK, TEXT } from '@suspensive/utils' -import { render, screen } from '@testing-library/react' -import { Suspense } from 'react' -import { Cache } from './Cache' -import { cacheOptions } from './cacheOptions' -import { CacheProvider } from './CacheProvider' -import { Read } from './Read' -import { useRead } from './useRead' - -const key = (id: number) => ['key', id] as const - -const successCache = () => cacheOptions({ cacheKey: key(1), cacheFn: () => Promise.resolve(TEXT) }) - -describe('cacheOptions', () => { - let cache: Cache - - beforeEach(() => { - cache = new Cache() - }) - - it('should be used with Read', async () => { - render( - - - {(cached) => <>{cached.data}} - - - ) - - expect(await screen.findByText(TEXT)).toBeInTheDocument() - }) - - it('should be used with useRead', async () => { - const CacheComponent = () => { - const cached = useRead(successCache()) - return <>{cached.data} - } - - render( - - - - - - ) - - expect(await screen.findByText(TEXT)).toBeInTheDocument() - }) -}) diff --git a/packages/cache/src/cacheOptions.test-d.tsx b/packages/cache/src/cacheOptions.test-d.tsx deleted file mode 100644 index e5eb218a1..000000000 --- a/packages/cache/src/cacheOptions.test-d.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { expectTypeOf } from 'vitest' -import type { ResolvedCached } from './Cache' -import { cacheOptions } from './cacheOptions' -import { Read } from './Read' -import { dataTagSymbol } from './types' -import { useRead } from './useRead' - -const key = (id: number) => ['key', id] as const - -const successCache = () => - cacheOptions({ - cacheKey: key(1), - cacheFn: () => Promise.resolve(5), - }) - -describe('cacheOptions', () => { - it('should be used with ', () => { - ;(() => ( - - {(cached) => { - expectTypeOf(cached).toEqualTypeOf['state']>() - expectTypeOf(cached.data).toEqualTypeOf() - return <> - }} - - ))() - }) - - it('should be used with useRead', () => { - const cached = useRead(successCache()) - expectTypeOf(cached).toEqualTypeOf['state']>() - expectTypeOf(cached.data).toEqualTypeOf() - }) - - it('should add DataTag on cacheKey with ReturnType', () => { - expectTypeOf(successCache().cacheKey[dataTagSymbol]).toEqualTypeOf() - }) -}) diff --git a/packages/cache/src/cacheOptions.ts b/packages/cache/src/cacheOptions.ts deleted file mode 100644 index bd57e93fc..000000000 --- a/packages/cache/src/cacheOptions.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { CacheKey, CacheOptions, DataTag } from './types' - -/** - * @experimental This is experimental feature. - */ -export function cacheOptions( - options: CacheOptions -): CacheOptions & { - cacheKey: DataTag -} - -/** - * @experimental This is experimental feature. - */ -export function cacheOptions(options: unknown) { - return options -} diff --git a/packages/cache/src/contexts/CacheContext.ts b/packages/cache/src/contexts/CacheContext.ts deleted file mode 100644 index 07e927c35..000000000 --- a/packages/cache/src/contexts/CacheContext.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { createContext } from 'react' -import type { Cache } from '../Cache' - -export const CacheContext = createContext(null) diff --git a/packages/cache/src/contexts/index.ts b/packages/cache/src/contexts/index.ts deleted file mode 100644 index 584cd5ae9..000000000 --- a/packages/cache/src/contexts/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { CacheContext } from './CacheContext' diff --git a/packages/cache/src/index.ts b/packages/cache/src/index.ts deleted file mode 100644 index cea614db3..000000000 --- a/packages/cache/src/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { Read } from './Read' -export { useRead } from './useRead' -export { cacheOptions } from './cacheOptions' -export { Cache } from './Cache' -export { CacheProvider } from './CacheProvider' -export { useCache } from './useCache' diff --git a/packages/cache/src/models/Subscribable.ts b/packages/cache/src/models/Subscribable.ts deleted file mode 100644 index aeeed145b..000000000 --- a/packages/cache/src/models/Subscribable.ts +++ /dev/null @@ -1,19 +0,0 @@ -type Listener = (...args: any[]) => unknown - -type Unsubscribe = () => void -type Subscribe = (listener: TListener) => Unsubscribe - -export class Subscribable { - protected listeners = new Set() - - public subscribe: Subscribe = (listener) => { - this.listeners.add(listener) - - const unsubscribe = (): void => { - this.listeners.delete(listener) - } - return unsubscribe - } - - protected notify = (): void => this.listeners.forEach((listener) => listener()) -} diff --git a/packages/cache/src/types.ts b/packages/cache/src/types.ts deleted file mode 100644 index 088b2bcf4..000000000 --- a/packages/cache/src/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { Tuple } from './utility-types' - -export type CacheKey = Tuple - -/** - * @experimental This is experimental feature. - */ -export interface CacheOptions { - cacheKey: TCacheKey - cacheFn: (options: { cacheKey: TCacheKey }) => Promise -} - -export declare const dataTagSymbol: unique symbol -export type DataTag = TType & { - [dataTagSymbol]: TValue -} diff --git a/packages/cache/src/useCache.ts b/packages/cache/src/useCache.ts deleted file mode 100644 index 44c78fcb9..000000000 --- a/packages/cache/src/useCache.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { useContext } from 'react' -import type { Cache } from './Cache' -import { CacheContext } from './contexts' - -/** - * @experimental This is experimental feature. - */ -export function useCache(): Cache { - const cache = useContext(CacheContext) - if (cache == null) { - throw new Error('CacheProvider should be in parent') - } - return cache -} diff --git a/packages/cache/src/useRead.spec.tsx b/packages/cache/src/useRead.spec.tsx deleted file mode 100644 index 9f7a1a44b..000000000 --- a/packages/cache/src/useRead.spec.tsx +++ /dev/null @@ -1,125 +0,0 @@ -import { ErrorBoundary, Suspense } from '@suspensive/react' -import { ERROR_MESSAGE, FALLBACK, TEXT, sleep } from '@suspensive/utils' -import { render, screen, waitFor } from '@testing-library/react' -import ms from 'ms' -import { Cache } from './Cache' -import { cacheOptions } from './cacheOptions' -import { CacheProvider } from './CacheProvider' -import { useCache } from './useCache' -import { useRead } from './useRead' - -const key = (id: string) => ['key', id] as const - -const successCache = () => - cacheOptions({ - cacheKey: key('success'), - cacheFn: () => sleep(ms('0.1s')).then(() => TEXT), - }) -const failureCache = () => - cacheOptions({ - cacheKey: key('failure'), - // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors - cacheFn: () => sleep(ms('0.1s')).then(() => Promise.reject(ERROR_MESSAGE)), - }) - -const ReadSuccess = () => { - const cached = useRead(successCache()) - const cache = useCache() - - return ( - <> - {cached.data} - - - ) -} - -const ReadFailure = () => { - const cached = useRead(failureCache()) - - return <>{cached.data} -} - -describe('useRead', () => { - let cache: Cache - - beforeEach(() => { - cache = new Cache() - cache.reset() - }) - - it('should return object containing data field with only success, and It will be cached', async () => { - const { unmount } = render( - - - - - - ) - expect(screen.queryByText(FALLBACK)).toBeInTheDocument() - await waitFor(() => expect(screen.queryByText(TEXT)).toBeInTheDocument()) - - // success data cache test - unmount() - render( - - - - - - ) - expect(screen.queryByText(FALLBACK)).not.toBeInTheDocument() - expect(screen.queryByText(TEXT)).toBeInTheDocument() - }) - - it('should throw Error, and It will be cached', async () => { - const { unmount } = render( - - <>{props.error}}> - - - - - - ) - expect(screen.queryByText(FALLBACK)).toBeInTheDocument() - await waitFor(() => expect(screen.queryByText(ERROR_MESSAGE)).toBeInTheDocument()) - - // error cache test - unmount() - render( - - <>{props.error}}> - - - - - - ) - expect(screen.queryByText(FALLBACK)).not.toBeInTheDocument() - expect(screen.queryByText(ERROR_MESSAGE)).toBeInTheDocument() - }) - - it('should return object containing reset method to reset cache by key', async () => { - const { rerender } = render( - - - - - - ) - expect(screen.queryByText(FALLBACK)).toBeInTheDocument() - await waitFor(() => expect(screen.queryByText(TEXT)).toBeInTheDocument()) - const resetButton = await screen.findByRole('button', { name: 'Try again' }) - resetButton.click() - rerender( - - - - - - ) - expect(screen.queryByText(FALLBACK)).toBeInTheDocument() - await waitFor(() => expect(screen.queryByText(TEXT)).toBeInTheDocument()) - }) -}) diff --git a/packages/cache/src/useRead.ts b/packages/cache/src/useRead.ts deleted file mode 100644 index 7e9972987..000000000 --- a/packages/cache/src/useRead.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { useSyncExternalStore } from 'react' -import type { ResolvedCached } from './Cache' -import type { CacheKey, CacheOptions } from './types' -import { useCache } from './useCache' - -/** - * @experimental This is experimental feature. - */ -export function useRead( - options: CacheOptions -): ResolvedCached['state'] { - const cache = useCache() - return useSyncExternalStore>( - cache.subscribe, - () => cache.suspend(options), - () => cache.suspend(options) - ).state -} diff --git a/packages/cache/src/utility-types/ExtractPartial.ts b/packages/cache/src/utility-types/ExtractPartial.ts deleted file mode 100644 index 9da388a4c..000000000 --- a/packages/cache/src/utility-types/ExtractPartial.ts +++ /dev/null @@ -1,4 +0,0 @@ -export type ExtractPartial, TExtractor extends Partial> = Extract< - TTarget, - TExtractor -> diff --git a/packages/cache/src/utility-types/Tuple.ts b/packages/cache/src/utility-types/Tuple.ts deleted file mode 100644 index 9a515a67a..000000000 --- a/packages/cache/src/utility-types/Tuple.ts +++ /dev/null @@ -1 +0,0 @@ -export type Tuple = TItem[] | readonly TItem[] diff --git a/packages/cache/src/utility-types/index.ts b/packages/cache/src/utility-types/index.ts deleted file mode 100644 index c07632b17..000000000 --- a/packages/cache/src/utility-types/index.ts +++ /dev/null @@ -1 +0,0 @@ -export type { Tuple } from './Tuple' diff --git a/packages/cache/src/utils/hashCacheKey.spec.ts b/packages/cache/src/utils/hashCacheKey.spec.ts deleted file mode 100644 index e2c663dd2..000000000 --- a/packages/cache/src/utils/hashCacheKey.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { hashCacheKey } from './hashCacheKey' - -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('hashCacheKey', () => { - it("should make same string regardless of key's field order", () => { - expect(hashCacheKey(key1) === hashCacheKey(key2)).toBe(true) - }) -}) diff --git a/packages/cache/src/utils/hashCacheKey.ts b/packages/cache/src/utils/hashCacheKey.ts deleted file mode 100644 index 07202db73..000000000 --- a/packages/cache/src/utils/hashCacheKey.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { CacheKey } from '../types' -import { type PlainObject, isPlainObject } from './isPlainObject' - -export const hashCacheKey = (key: CacheKey) => - JSON.stringify(key, (_, val: unknown) => - isPlainObject(val) - ? Object.keys(val) - .sort() - .reduce((acc: PlainObject, cur) => { - acc[cur] = val[cur] - return acc - }, {}) - : val - ) diff --git a/packages/cache/src/utils/index.ts b/packages/cache/src/utils/index.ts deleted file mode 100644 index 57f4d7951..000000000 --- a/packages/cache/src/utils/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { hashCacheKey } from './hashCacheKey' diff --git a/packages/cache/src/utils/isPlainObject.spec.ts b/packages/cache/src/utils/isPlainObject.spec.ts deleted file mode 100644 index e761544b1..000000000 --- a/packages/cache/src/utils/isPlainObject.spec.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { isPlainObject } from './isPlainObject' - -describe('isPlainObject', () => { - describe('true cases', () => { - 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) - }) - }) - - describe('false cases', () => { - 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/cache/src/utils/isPlainObject.ts b/packages/cache/src/utils/isPlainObject.ts deleted file mode 100644 index 96f0c5610..000000000 --- a/packages/cache/src/utils/isPlainObject.ts +++ /dev/null @@ -1,29 +0,0 @@ -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/cache/tsconfig.json b/packages/cache/tsconfig.json deleted file mode 100644 index 2176a2e69..000000000 --- a/packages/cache/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "@suspensive/tsconfig/react-library.json", - "include": [".", "eslint.config.mjs"], - "compilerOptions": { - "types": ["@testing-library/jest-dom/vitest", "vitest/globals"] - } -} diff --git a/packages/cache/tsup.config.ts b/packages/cache/tsup.config.ts deleted file mode 100644 index 9560a461a..000000000 --- a/packages/cache/tsup.config.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { options } from '@suspensive/tsup' -import { defineConfig } from 'tsup' - -export default defineConfig(options) diff --git a/packages/cache/vitest.config.ts b/packages/cache/vitest.config.ts deleted file mode 100644 index fa9d99e50..000000000 --- a/packages/cache/vitest.config.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { defineConfig } from 'vitest/config' -import packageJson from './package.json' - -export default defineConfig({ - test: { - name: packageJson.name, - dir: './src', - environment: 'jsdom', - globals: true, - setupFiles: './vitest.setup.ts', - coverage: { - provider: 'istanbul', - }, - }, -}) diff --git a/packages/cache/vitest.setup.ts b/packages/cache/vitest.setup.ts deleted file mode 100644 index e87ca3f0a..000000000 --- a/packages/cache/vitest.setup.ts +++ /dev/null @@ -1,7 +0,0 @@ -import '@testing-library/jest-dom/vitest' -import { cleanup } from '@testing-library/react' -import { afterEach } from 'vitest' - -afterEach(() => { - cleanup() -}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2574f1fd5..6bdb65d45 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -468,9 +468,6 @@ importers: examples/visualization: dependencies: - '@suspensive/cache': - specifier: workspace:* - version: link:../../packages/cache '@suspensive/react': specifier: workspace:* version: link:../../packages/react @@ -570,31 +567,6 @@ importers: specifier: ^15.9.0 version: 15.9.0 - packages/cache: - dependencies: - '@suspensive/utils': - specifier: workspace:* - version: link:../utils - devDependencies: - '@suspensive/eslint-config': - specifier: workspace:* - version: link:../../configs/eslint-config - '@suspensive/react': - specifier: workspace:* - version: link:../react - '@suspensive/tsconfig': - specifier: workspace:* - version: link:../../configs/tsconfig - '@suspensive/tsup': - specifier: workspace:* - version: link:../../configs/tsup - '@types/react': - specifier: catalog:react18 - version: 18.3.5 - react: - specifier: catalog:react18 - version: 18.3.1 - packages/jotai: dependencies: '@suspensive/utils':