├── .changeset ├── README.md └── config.json ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug.yml │ └── feature_request.yml ├── PULL_REQUEST_TEMPLATE.md ├── actions │ └── pnpm-setup-node │ │ └── action.yml ├── dependabot.yml ├── labeler.yml └── workflows │ ├── broken-link-checker.yml │ ├── ci.yml │ ├── graph.yml │ ├── knip.yml │ ├── labeler.yml │ └── release.yml ├── .gitignore ├── .husky └── pre-commit ├── .lintstagedrc ├── .npmrc ├── .nvmrc ├── .prettierignore ├── .vscode ├── extensions.json └── settings.json ├── CNAME ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── assets ├── logo_background.png ├── logo_background_star.png └── logo_dark.png ├── codecov.yml ├── configs ├── eslint-config │ ├── CHANGELOG.md │ ├── index.js │ └── package.json ├── tsconfig │ ├── base.json │ ├── nextjs.json │ ├── package.json │ └── react-library.json └── tsup │ ├── eslint.config.mjs │ ├── package.json │ ├── src │ └── index.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── docs └── suspensive.org │ ├── .gitignore │ ├── README.md │ ├── eslint.config.mjs │ ├── next.config.mjs │ ├── package.json │ ├── postcss.config.js │ ├── prettier.config.mjs │ ├── public │ ├── img │ │ ├── banner.png │ │ ├── errorBoundary-shouldcatch-prop.png │ │ ├── favicon.ico │ │ ├── homepage_background.svg │ │ ├── homepage_logo.png │ │ ├── icons │ │ │ ├── check.svg │ │ │ └── content_copy.svg │ │ ├── logo_background.png │ │ ├── logo_background_star.png │ │ ├── logo_dark.png │ │ ├── logo_light.png │ │ ├── logo_not_cropped.png │ │ ├── react-query_community-resources.png │ │ ├── react-query_private-class-fields-error.png │ │ ├── react-query_private-class-fields-tkdodo-comment.png │ │ └── suspense-in-ssr-error.png │ └── logo_dark.svg │ ├── src │ ├── app │ │ ├── [lang] │ │ │ ├── [[...mdxPath]] │ │ │ │ ├── FadeIn.tsx │ │ │ │ ├── MDXContent.tsx │ │ │ │ └── page.tsx │ │ │ ├── _components │ │ │ │ └── Logo.tsx │ │ │ ├── layout.tsx │ │ │ ├── not-found.ts │ │ │ └── styles.css │ │ ├── _dictionaries │ │ │ ├── en.tsx │ │ │ ├── get-dictionary.ts │ │ │ └── ko.tsx │ │ └── favicon.ico │ ├── components │ │ ├── BorderTrail.tsx │ │ ├── BubbleChart.tsx │ │ ├── Callout.tsx │ │ ├── GlowEffect.tsx │ │ ├── HomePage.tsx │ │ ├── Magnetic.tsx │ │ ├── NpmInstallCopyButton.tsx │ │ ├── Sandpack │ │ │ ├── ConsoleCounterButton.tsx │ │ │ ├── CustomPreset.tsx │ │ │ ├── ErrorOverlay.tsx │ │ │ ├── SandPackCSS.tsx │ │ │ ├── baseTemplate.ts │ │ │ └── index.tsx │ │ ├── Scrollycoding.tsx │ │ ├── SectionText.tsx │ │ ├── Spotlight.tsx │ │ ├── TextShimmer.tsx │ │ ├── Tilt.tsx │ │ └── index.ts │ ├── content │ │ ├── en │ │ │ ├── _meta.tsx │ │ │ ├── docs │ │ │ │ ├── _meta.tsx │ │ │ │ ├── changelogs.mdx │ │ │ │ ├── codemods │ │ │ │ │ ├── _meta.tsx │ │ │ │ │ ├── migrateQueryClientConsumerProps.mdx │ │ │ │ │ ├── migrateWithAPI.mdx │ │ │ │ │ ├── motivation.mdx │ │ │ │ │ ├── removeNetworkmode.mdx │ │ │ │ │ ├── tanstackQueryImport.mdx │ │ │ │ │ └── usage.mdx │ │ │ │ ├── contributors.mdx │ │ │ │ ├── introduction.mdx │ │ │ │ ├── jotai │ │ │ │ │ ├── Atom.mdx │ │ │ │ │ ├── AtomValue.mdx │ │ │ │ │ ├── SetAtom.mdx │ │ │ │ │ ├── _meta.tsx │ │ │ │ │ ├── installation.mdx │ │ │ │ │ └── motivation.mdx │ │ │ │ ├── links.mdx │ │ │ │ ├── migration │ │ │ │ │ ├── _meta.tsx │ │ │ │ │ ├── migrate-to-v2.mdx │ │ │ │ │ └── migrate-to-v3.mdx │ │ │ │ ├── react-dom │ │ │ │ │ ├── InView.mdx │ │ │ │ │ ├── _meta.tsx │ │ │ │ │ └── installation.mdx │ │ │ │ ├── react-query │ │ │ │ │ ├── Mutation.mdx │ │ │ │ │ ├── PrefetchInfiniteQuery.mdx │ │ │ │ │ ├── PrefetchQuery.mdx │ │ │ │ │ ├── QueryClientConsumer.mdx │ │ │ │ │ ├── SuspenseInfiniteQuery.mdx │ │ │ │ │ ├── SuspenseQueries.mdx │ │ │ │ │ ├── SuspenseQuery.mdx │ │ │ │ │ ├── _meta.tsx │ │ │ │ │ ├── infiniteQueryOptions.mdx │ │ │ │ │ ├── installation.mdx │ │ │ │ │ ├── migration │ │ │ │ │ │ ├── _meta.tsx │ │ │ │ │ │ ├── migrate-to-v2.mdx │ │ │ │ │ │ └── migrate-to-v3.mdx │ │ │ │ │ ├── motivation.mdx │ │ │ │ │ ├── mutationOptions.mdx │ │ │ │ │ ├── queryOptions.mdx │ │ │ │ │ ├── tanstack-query-compatibility.mdx │ │ │ │ │ ├── usePrefetchInfiniteQuery.mdx │ │ │ │ │ ├── usePrefetchQuery.mdx │ │ │ │ │ ├── useSuspenseInfiniteQuery.mdx │ │ │ │ │ ├── useSuspenseQueries.mdx │ │ │ │ │ └── useSuspenseQuery.mdx │ │ │ │ └── react │ │ │ │ │ ├── ClientOnly.mdx │ │ │ │ │ ├── DefaultPropsProvider.mdx │ │ │ │ │ ├── Delay.mdx │ │ │ │ │ ├── ErrorBoundary.mdx │ │ │ │ │ ├── ErrorBoundaryGroup.mdx │ │ │ │ │ ├── Suspense.mdx │ │ │ │ │ ├── _meta.tsx │ │ │ │ │ ├── installation.mdx │ │ │ │ │ ├── migration │ │ │ │ │ ├── _meta.tsx │ │ │ │ │ ├── migrate-to-v2.mdx │ │ │ │ │ └── migrate-to-v3.mdx │ │ │ │ │ └── motivation.mdx │ │ │ └── index.mdx │ │ └── ko │ │ │ ├── _meta.tsx │ │ │ ├── docs │ │ │ ├── _meta.tsx │ │ │ ├── changelogs.mdx │ │ │ ├── codemods │ │ │ │ ├── _meta.tsx │ │ │ │ ├── migrateQueryClientConsumerProps.mdx │ │ │ │ ├── migrateWithAPI.mdx │ │ │ │ ├── motivation.mdx │ │ │ │ ├── removeNetworkmode.mdx │ │ │ │ ├── tanstackQueryImport.mdx │ │ │ │ └── usage.mdx │ │ │ ├── contributors.mdx │ │ │ ├── introduction.mdx │ │ │ ├── jotai │ │ │ │ ├── Atom.mdx │ │ │ │ ├── AtomValue.mdx │ │ │ │ ├── SetAtom.mdx │ │ │ │ ├── _meta.tsx │ │ │ │ ├── installation.mdx │ │ │ │ └── motivation.mdx │ │ │ ├── links.mdx │ │ │ ├── migration │ │ │ │ ├── _meta.tsx │ │ │ │ ├── migrate-to-v2.mdx │ │ │ │ └── migrate-to-v3.mdx │ │ │ ├── react-dom │ │ │ │ ├── InView.mdx │ │ │ │ ├── _meta.tsx │ │ │ │ └── installation.mdx │ │ │ ├── react-query │ │ │ │ ├── Mutation.mdx │ │ │ │ ├── PrefetchInfiniteQuery.mdx │ │ │ │ ├── PrefetchQuery.mdx │ │ │ │ ├── QueryClientConsumer.mdx │ │ │ │ ├── SuspenseInfiniteQuery.mdx │ │ │ │ ├── SuspenseQueries.mdx │ │ │ │ ├── SuspenseQuery.mdx │ │ │ │ ├── _meta.tsx │ │ │ │ ├── infiniteQueryOptions.mdx │ │ │ │ ├── installation.mdx │ │ │ │ ├── migration │ │ │ │ │ ├── _meta.tsx │ │ │ │ │ ├── migrate-to-v2.mdx │ │ │ │ │ └── migrate-to-v3.mdx │ │ │ │ ├── motivation.mdx │ │ │ │ ├── mutationOptions.mdx │ │ │ │ ├── queryOptions.mdx │ │ │ │ ├── tanstack-query-compatibility.mdx │ │ │ │ ├── usePrefetchInfiniteQuery.mdx │ │ │ │ ├── usePrefetchQuery.mdx │ │ │ │ ├── useSuspenseInfiniteQuery.mdx │ │ │ │ ├── useSuspenseQueries.mdx │ │ │ │ └── useSuspenseQuery.mdx │ │ │ └── react │ │ │ │ ├── ClientOnly.mdx │ │ │ │ ├── DefaultPropsProvider.mdx │ │ │ │ ├── Delay.mdx │ │ │ │ ├── ErrorBoundary.mdx │ │ │ │ ├── ErrorBoundaryGroup.mdx │ │ │ │ ├── Suspense.mdx │ │ │ │ ├── _meta.tsx │ │ │ │ ├── installation.mdx │ │ │ │ ├── migration │ │ │ │ ├── _meta.tsx │ │ │ │ ├── migrate-to-v2.mdx │ │ │ │ └── migrate-to-v3.mdx │ │ │ │ └── motivation.mdx │ │ │ └── index.mdx │ ├── mdx-components.ts │ └── middleware.ts │ ├── svg.d.ts │ └── tsconfig.json ├── examples ├── next-streaming-react-query │ ├── .gitignore │ ├── eslint.config.mjs │ ├── next.config.mjs │ ├── package.json │ ├── postcss.config.js │ ├── prettier.config.mjs │ ├── public │ │ ├── next.svg │ │ └── vercel.svg │ ├── src │ │ ├── app │ │ │ ├── api │ │ │ │ └── text │ │ │ │ │ └── route.ts │ │ │ ├── favicon.ico │ │ │ ├── globals.css │ │ │ ├── layout.tsx │ │ │ ├── page.tsx │ │ │ ├── providers.tsx │ │ │ └── test │ │ │ │ └── page.tsx │ │ └── query │ │ │ └── index.ts │ └── tsconfig.json ├── react-native-playground │ ├── .gitignore │ ├── README.md │ ├── app.json │ ├── app │ │ ├── +not-found.tsx │ │ ├── _layout.tsx │ │ └── index.tsx │ ├── assets │ │ └── images │ │ │ ├── adaptive-icon.png │ │ │ ├── favicon.png │ │ │ ├── icon.png │ │ │ └── splash-icon.png │ ├── eslint.config.mjs │ ├── package.json │ └── tsconfig.json ├── visualization │ ├── .gitignore │ ├── eslint.config.mjs │ ├── next.config.mjs │ ├── package.json │ ├── postcss.config.js │ ├── prettier.config.mjs │ ├── public │ │ └── logo_not_cropped.png │ ├── src │ │ ├── app │ │ │ ├── api │ │ │ │ └── delay │ │ │ │ │ └── route.ts │ │ │ ├── favicon.ico │ │ │ ├── global.css │ │ │ ├── layout.tsx │ │ │ ├── page.tsx │ │ │ ├── providers.tsx │ │ │ ├── react-dom │ │ │ │ ├── FadeIn │ │ │ │ │ └── page.tsx │ │ │ │ └── InView │ │ │ │ │ └── page.tsx │ │ │ ├── react-query │ │ │ │ ├── SuspenseInfiniteQuery │ │ │ │ │ └── page.tsx │ │ │ │ ├── SuspenseQuery │ │ │ │ │ └── page.tsx │ │ │ │ └── page.tsx │ │ │ └── react │ │ │ │ ├── Delay │ │ │ │ └── page.tsx │ │ │ │ ├── ErrorBoundary │ │ │ │ ├── ErrorInFallback │ │ │ │ │ └── page.tsx │ │ │ │ └── shouldCatch │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── renderPhase │ │ │ │ │ └── page.tsx │ │ │ │ ├── page.tsx │ │ │ │ ├── useErrorBoundary │ │ │ │ └── page.tsx │ │ │ │ ├── useSyncExternalStore │ │ │ │ └── page.tsx │ │ │ │ ├── wrap │ │ │ │ └── page.tsx │ │ │ │ └── zodSearchParams │ │ │ │ └── page.tsx │ │ ├── components │ │ │ ├── Throw.tsx │ │ │ └── uis │ │ │ │ └── index.tsx │ │ ├── hooks │ │ │ ├── index.ts │ │ │ └── useTimeout.ts │ │ └── utils │ │ │ ├── api.ts │ │ │ ├── delay.ts │ │ │ └── index.ts │ └── tsconfig.json └── vite-react-18-suspense-prerender-siblings-problem │ ├── eslint.config.mjs │ ├── index.html │ ├── package.json │ ├── src │ ├── App.css │ ├── App.tsx │ ├── index.css │ ├── main.tsx │ └── vite-env.d.ts │ ├── tsconfig.json │ ├── tsconfig.tsbuildinfo │ └── vite.config.ts ├── knip.json ├── package.json ├── packages ├── codemods │ ├── CHANGELOG.md │ ├── README.md │ ├── eslint.config.mjs │ ├── package.json │ ├── src │ │ ├── bin │ │ │ ├── codemods.spec.ts │ │ │ ├── codemods.ts │ │ │ ├── transformRunner.spec.ts │ │ │ └── transformRunner.ts │ │ └── transforms │ │ │ ├── migrate-query-client-consumer-props.ts │ │ │ ├── migrate-with-api.ts │ │ │ ├── remove-networkmode.ts │ │ │ ├── tanstack-query-import.ts │ │ │ ├── testfixtures │ │ │ ├── migrate-query-client-consumer-props │ │ │ │ ├── migrate-query-client-consumer-props.input.jsx │ │ │ │ └── migrate-query-client-consumer-props.output.jsx │ │ │ ├── migrate-with-api │ │ │ │ ├── migrate-with-api.input.jsx │ │ │ │ └── migrate-with-api.output.jsx │ │ │ ├── remove-networkmode │ │ │ │ ├── remove-networkmode.input.jsx │ │ │ │ └── remove-networkmode.output.jsx │ │ │ └── tanstack-query-import │ │ │ │ ├── tanstack-query-import.input.jsx │ │ │ │ └── tanstack-query-import.output.jsx │ │ │ ├── tests │ │ │ ├── migrate-query-client-consumer-props.test.ts │ │ │ ├── migrate-with-api.test.ts │ │ │ ├── remove-networkmode.test.ts │ │ │ └── tanstack-query-import.test.ts │ │ │ └── utils │ │ │ ├── createParserFromPath.spec.ts │ │ │ ├── createParserFromPath.ts │ │ │ ├── getTestfixtures.spec.ts │ │ │ └── getTestfixtures.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ └── vitest.config.ts ├── jotai │ ├── CHANGELOG.md │ ├── LICENSE │ ├── eslint.config.mjs │ ├── package.json │ ├── src │ │ ├── Atom.spec.tsx │ │ ├── Atom.test-d.tsx │ │ ├── Atom.tsx │ │ ├── AtomValue.spec.tsx │ │ ├── AtomValue.test-d.tsx │ │ ├── AtomValue.tsx │ │ ├── SetAtom.spec.tsx │ │ ├── SetAtom.test-d.tsx │ │ ├── SetAtom.tsx │ │ ├── index.ts │ │ └── utility-types │ │ │ ├── ChildrenRenderProps.ts │ │ │ ├── SetAtom.ts │ │ │ └── index.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ └── vitest.setup.ts ├── react-dom │ ├── CHANGELOG.md │ ├── LICENSE │ ├── eslint.config.mjs │ ├── package.json │ ├── src │ │ ├── FadeIn.spec.tsx │ │ ├── FadeIn.test-d.tsx │ │ ├── FadeIn.tsx │ │ ├── InView.spec.tsx │ │ ├── InView.tsx │ │ ├── browser │ │ │ └── browser.spec.tsx │ │ ├── index.ts │ │ ├── test-utils │ │ │ └── index.ts │ │ ├── useFadeIn.spec.tsx │ │ ├── useFadeIn.ts │ │ ├── useInView.spec.tsx │ │ ├── useInView.tsx │ │ ├── utility-types │ │ │ ├── OmitKeyof.test-d.ts │ │ │ ├── OmitKeyof.ts │ │ │ └── index.ts │ │ └── utils │ │ │ ├── observe.spec.ts │ │ │ └── observe.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ ├── vitest.setup.ts │ └── vitest.workspace.ts ├── react-native │ ├── CHANGELOG.md │ ├── LICENSE │ ├── babel.config.cjs │ ├── eslint.config.mjs │ ├── jest.config.ts │ ├── jest.setup.ts │ ├── package.json │ ├── src │ │ ├── TestText.spec.tsx │ │ ├── TestText.tsx │ │ └── index.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── react-query-4 │ ├── CHANGELOG.md │ ├── LICENSE │ ├── eslint.config.mjs │ ├── package.json │ ├── src │ │ ├── Mutation.test-d.tsx │ │ ├── Mutation.tsx │ │ ├── PrefetchInfiniteQuery.test-d.tsx │ │ ├── PrefetchInfiniteQuery.tsx │ │ ├── PrefetchQuery.test-d.tsx │ │ ├── PrefetchQuery.tsx │ │ ├── QueryClientConsumer.test-d.tsx │ │ ├── QueryClientConsumer.tsx │ │ ├── SuspenseInfiniteQuery.test-d.tsx │ │ ├── SuspenseInfiniteQuery.tsx │ │ ├── SuspenseQueries.test-d.tsx │ │ ├── SuspenseQueries.tsx │ │ ├── SuspenseQuery.test-d.tsx │ │ ├── SuspenseQuery.tsx │ │ ├── index.ts │ │ ├── infiniteQueryOptions.test-d.tsx │ │ ├── infiniteQueryOptions.ts │ │ ├── mutationOptions.test-d.tsx │ │ ├── mutationOptions.tsx │ │ ├── queryOptions.test-d.tsx │ │ ├── queryOptions.ts │ │ ├── test-utils │ │ │ └── index.ts │ │ ├── usePrefetchInfiniteQuery.test-d.tsx │ │ ├── usePrefetchInfiniteQuery.ts │ │ ├── usePrefetchQuery.test-d.tsx │ │ ├── usePrefetchQuery.ts │ │ ├── useSuspenseInfiniteQuery.test-d.ts │ │ ├── useSuspenseInfiniteQuery.ts │ │ ├── useSuspenseQueries.test-d.ts │ │ ├── useSuspenseQueries.ts │ │ ├── useSuspenseQuery.test-d.ts │ │ ├── useSuspenseQuery.ts │ │ └── utility-types │ │ │ ├── OmitKeyof.test-d.ts │ │ │ ├── OmitKeyof.ts │ │ │ ├── RequiredKeyof.ts │ │ │ └── index.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ └── vitest.setup.ts ├── react-query-5 │ ├── CHANGELOG.md │ ├── LICENSE │ ├── eslint.config.mjs │ ├── package.json │ ├── src │ │ ├── Mutation.test-d.tsx │ │ ├── Mutation.tsx │ │ ├── PrefetchInfiniteQuery.test-d.tsx │ │ ├── PrefetchInfiniteQuery.tsx │ │ ├── PrefetchQuery.test-d.tsx │ │ ├── PrefetchQuery.tsx │ │ ├── QueryClientConsumer.test-d.tsx │ │ ├── QueryClientConsumer.tsx │ │ ├── SuspenseInfiniteQuery.test-d.tsx │ │ ├── SuspenseInfiniteQuery.tsx │ │ ├── SuspenseQueries.test-d.tsx │ │ ├── SuspenseQueries.tsx │ │ ├── SuspenseQuery.test-d.tsx │ │ ├── SuspenseQuery.tsx │ │ ├── index.ts │ │ ├── infiniteQueryOptions.ts │ │ ├── mutationOptions.test-d.tsx │ │ ├── mutationOptions.tsx │ │ ├── queryOptions.ts │ │ ├── test-utils │ │ │ └── index.ts │ │ ├── usePrefetchInfiniteQuery.ts │ │ ├── usePrefetchQuery.ts │ │ ├── useSuspenseInfiniteQuery.ts │ │ ├── useSuspenseQueries.ts │ │ └── useSuspenseQuery.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ └── vitest.setup.ts ├── react-query │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.ko.md │ ├── README.md │ ├── eslint.config.mjs │ ├── package.json │ ├── src │ │ ├── bin │ │ │ ├── cli.spec.ts │ │ │ ├── cli.ts │ │ │ ├── postinstall.spec.ts │ │ │ ├── postinstall.ts │ │ │ └── utils │ │ │ │ ├── commands.spec.ts │ │ │ │ ├── commands.ts │ │ │ │ ├── copy.spec.ts │ │ │ │ ├── copy.ts │ │ │ │ ├── logger.spec.ts │ │ │ │ ├── logger.ts │ │ │ │ ├── package.spec.ts │ │ │ │ ├── package.ts │ │ │ │ ├── switchVersion.spec.ts │ │ │ │ ├── switchVersion.ts │ │ │ │ └── table.ts │ │ ├── index.ts │ │ ├── v4.ts │ │ └── v5.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ └── vitest.setup.ts └── react │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.ko.md │ ├── README.md │ ├── eslint.config.mjs │ ├── package.json │ ├── src │ ├── ClientOnly.spec.tsx │ ├── ClientOnly.tsx │ ├── DefaultProps.spec.tsx │ ├── DefaultProps.tsx │ ├── Delay.spec.tsx │ ├── Delay.test-d.tsx │ ├── Delay.tsx │ ├── ErrorBoundary.spec.tsx │ ├── ErrorBoundary.test-d.tsx │ ├── ErrorBoundary.tsx │ ├── ErrorBoundaryGroup.spec.tsx │ ├── ErrorBoundaryGroup.test-d.tsx │ ├── ErrorBoundaryGroup.tsx │ ├── Suspense.spec.tsx │ ├── Suspense.tsx │ ├── contexts │ │ ├── DefaultPropsContexts.ts │ │ └── index.ts │ ├── hooks │ │ ├── index.ts │ │ ├── useIsChanged.spec.ts │ │ ├── useIsChanged.ts │ │ ├── useIsClient.spec.tsx │ │ ├── useIsClient.ts │ │ ├── usePrevious.spec.ts │ │ ├── usePrevious.ts │ │ ├── useTimeout.spec.tsx │ │ └── useTimeout.ts │ ├── index.ts │ ├── models │ │ ├── SuspensiveError.spec.tsx │ │ └── SuspensiveError.ts │ ├── test-utils │ │ └── index.tsx │ ├── utility-types │ │ ├── ConstructorType.ts │ │ ├── OmitKeyof.test-d.ts │ │ ├── OmitKeyof.ts │ │ ├── PropsWithoutChildren.ts │ │ └── index.ts │ └── utils │ │ ├── defineSuspense.spec.ts │ │ ├── defineSuspense.test-d.ts │ │ ├── defineSuspense.tsx │ │ ├── hasResetKeysChanged.spec.ts │ │ ├── hasResetKeysChanged.ts │ │ ├── increase.ts │ │ ├── index.ts │ │ └── noop.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── vitest.config.ts │ └── vitest.setup.ts ├── packlint.config.mjs ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── prettier.config.mjs └── turbo.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", 3 | "changelog": ["@changesets/changelog-github", { "repo": "toss/suspensive" }], 4 | "commit": false, 5 | "fixed": [ 6 | [ 7 | "@suspensive/react", 8 | "@suspensive/react-dom", 9 | "@suspensive/react-query", 10 | "@suspensive/react-query-4", 11 | "@suspensive/react-query-5", 12 | "@suspensive/jotai", 13 | "@suspensive/codemods" 14 | ] 15 | ], 16 | "ignore": [ 17 | "@suspensive/suspensive.org", 18 | "@suspensive/next-streaming-react-query", 19 | "@suspensive/react-native-playground", 20 | "@suspensive/visualization" 21 | ], 22 | "linked": [], 23 | "access": "restricted", 24 | "baseBranch": "main", 25 | "updateInternalDependencies": "patch", 26 | "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { 27 | "onlyUpdatePeerDependentsWhenOutOfRange": true 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @manudeli 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Suggest an idea 3 | labels: [feature] 4 | title: "[Feature]:" 5 | body: 6 | - type: dropdown 7 | id: package 8 | attributes: 9 | label: Package Scope 10 | description: Is this issue related to a specific package? 11 | multiple: true 12 | options: 13 | - "@suspensive/react" 14 | - "@suspensive/react-dom" 15 | - "@suspensive/react-native" 16 | - "@suspensive/react-query" 17 | - "@suspensive/react-query-4" 18 | - "@suspensive/react-query-5" 19 | - "@suspensive/jotai" 20 | - "@suspensive/codemods" 21 | - etc 22 | validations: 23 | required: true 24 | 25 | - type: textarea 26 | id: description 27 | attributes: 28 | description: Description what feature you want 29 | label: Description 30 | validations: 31 | required: true 32 | 33 | - type: textarea 34 | id: possible-solution 35 | attributes: 36 | label: Possible Solution 37 | description: If you have suggestions on a fix for the bug 38 | placeholder: I think this is probably... 39 | validations: 40 | required: false 41 | 42 | - type: textarea 43 | id: etc 44 | attributes: 45 | label: etc. 46 | validations: 47 | required: false 48 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | 6 | 7 | ## PR Checklist 8 | 9 | - [ ] I did below actions if need 10 | 11 | 1. I read the [Contributing Guide](https://github.com/toss/suspensive/blob/main/CONTRIBUTING.md) 12 | 2. I added documents and tests. 13 | -------------------------------------------------------------------------------- /.github/actions/pnpm-setup-node/action.yml: -------------------------------------------------------------------------------- 1 | name: setup pnpm & node 2 | description: setup pnpm & node 3 | runs: 4 | using: composite 5 | steps: 6 | - uses: pnpm/action-setup@v4 7 | - uses: actions/setup-node@v4 8 | with: 9 | node-version-file: '.nvmrc' 10 | cache: 'pnpm' 11 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "npm" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "monthly" 12 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | "@suspensive/react": 2 | - "packages/react/**/*" 3 | "@suspensive/react-dom": 4 | - "packages/react-dom/**/*" 5 | "@suspensive/react-native": 6 | - "packages/react-native/**/*" 7 | "@suspensive/react-query": 8 | - "packages/react-query/**/*" 9 | "@suspensive/react-query-4": 10 | - "packages/react-query-4/**/*" 11 | "@suspensive/react-query-5": 12 | - "packages/react-query-5/**/*" 13 | "@suspensive/jotai": 14 | - "packages/jotai/**/*" 15 | "@suspensive/codemods": 16 | - "packages/codemods/**/*" 17 | "suspensive.org": 18 | - "docs/suspensive.org/**/*" 19 | "examples": 20 | - "examples/**/*" 21 | "eslint": 22 | - "configs/eslint/**/*" 23 | - "**/.eslint*" 24 | "tsconfig": 25 | - "configs/tsconfig/**/*" 26 | - "**/.tsconfig*" 27 | "dependencies": 28 | - "pnpm-lock.yaml" 29 | "workflows": 30 | - ".github/workflows/**/*" 31 | -------------------------------------------------------------------------------- /.github/workflows/broken-link-checker.yml: -------------------------------------------------------------------------------- 1 | name: Broken link checker 2 | 3 | on: 4 | schedule: 5 | - cron: '0 5 * * 1-5' 6 | workflow_dispatch: 7 | 8 | jobs: 9 | broken-link-checker: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: ./.github/actions/pnpm-setup-node 14 | - run: pnpm install 15 | - run: pnpm run blc:suspensive.org 16 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [main, beta, next, v1, v2, v3] 6 | pull_request: 7 | types: [opened, synchronize, reopened] 8 | env: 9 | CI: ${{ vars.CI }} 10 | TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} 11 | TURBO_TEAM: ${{ vars.TURBO_TEAM }} 12 | 13 | jobs: 14 | quality: 15 | name: Check quality 16 | runs-on: ubuntu-latest 17 | strategy: 18 | matrix: 19 | command: ['prepack', 'ci:attw', 'ci:eslint', 'ci:publint', 'ci:sherif', 'ci:type', 'ci:test', 'build'] 20 | steps: 21 | - uses: actions/checkout@v4 22 | - uses: ./.github/actions/pnpm-setup-node 23 | - run: pnpm install 24 | - if: matrix.command == 'ci:test' 25 | run: pnpm playwright install 26 | - run: pnpm run ${{ matrix.command }} 27 | - if: matrix.command == 'ci:test' 28 | uses: codecov/codecov-action@v5 29 | env: 30 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 31 | - if: matrix.command == 'prepack' 32 | uses: preactjs/compressed-size-action@v2 33 | with: 34 | build-script: 'prepack' 35 | pattern: 'packages/**/dist/*.{js,cjs,mjs}' 36 | exclude: '{**/*.map,**/node_modules/**,**/dist/chunk-*.{js,cjs,mjs}}' 37 | repo-token: ${{ secrets.GITHUB_TOKEN }} 38 | -------------------------------------------------------------------------------- /.github/workflows/graph.yml: -------------------------------------------------------------------------------- 1 | name: Deploy graph site to Pages 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | permissions: 8 | contents: read 9 | pages: write 10 | id-token: write 11 | 12 | concurrency: 13 | group: 'pages' 14 | cancel-in-progress: false 15 | 16 | jobs: 17 | build: 18 | name: Build 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v4 22 | - uses: ./.github/actions/pnpm-setup-node 23 | - name: Setup Pages 24 | uses: actions/configure-pages@v3 25 | - name: Install dependencies 26 | run: pnpm install 27 | - name: Build with Turbo graph 28 | run: pnpm run graph 29 | - name: Upload artifact 30 | uses: actions/upload-pages-artifact@v3 31 | with: 32 | path: ./graph 33 | 34 | deploy: 35 | environment: 36 | name: github-pages 37 | url: ${{ steps.deployment.outputs.page_url }} 38 | runs-on: ubuntu-latest 39 | needs: build 40 | steps: 41 | - name: Deploy to GitHub Pages 42 | id: deployment 43 | uses: actions/deploy-pages@v4.0.5 44 | -------------------------------------------------------------------------------- /.github/workflows/knip.yml: -------------------------------------------------------------------------------- 1 | name: Knip 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | types: [opened, synchronize, reopened] 8 | env: 9 | CI: ${{ vars.CI }} 10 | concurrency: 11 | group: ${{ github.workflow }}-${{ github.ref }} 12 | cancel-in-progress: true 13 | 14 | jobs: 15 | knip: 16 | name: Knip 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v4 20 | - uses: ./.github/actions/pnpm-setup-node 21 | - run: pnpm install 22 | - run: pnpm run ci:knip 23 | -------------------------------------------------------------------------------- /.github/workflows/labeler.yml: -------------------------------------------------------------------------------- 1 | name: Labeler 2 | 3 | on: 4 | - pull_request_target 5 | 6 | concurrency: 7 | group: ${{ github.workflow }}-${{ github.ref }} 8 | cancel-in-progress: true 9 | 10 | jobs: 11 | triage: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/labeler@v4 15 | with: 16 | repo-token: ${{ secrets.GITHUB_TOKEN }} 17 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Changesets PR or Publish 2 | 3 | on: 4 | push: 5 | branches: [main, beta, next] 6 | env: 7 | TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} 8 | TURBO_TEAM: ${{ vars.TURBO_TEAM }} 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | permissions: 14 | id-token: write 15 | contents: write 16 | steps: 17 | - uses: actions/checkout@v4 18 | - uses: ./.github/actions/pnpm-setup-node 19 | - run: pnpm install 20 | - run: | 21 | git config --global user.name "Jonghyeon Ko" 22 | git config --global user.email "jonghyeon@toss.im" 23 | - name: Create Changesets Pull Request or Publish to NPM 24 | id: changesets 25 | uses: changesets/action@v1 26 | with: 27 | title: 'chore: version packages' 28 | commit: 'chore: version packages' 29 | version: pnpm run changeset:version 30 | publish: pnpm run changeset:publish 31 | setupGitUser: false 32 | env: 33 | GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} 34 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # testing 7 | coverage 8 | __screenshots__ 9 | vitest.config.ts.timestamp* 10 | tsconfig.vitest-temp.json 11 | 12 | # next.js 13 | .next/ 14 | out/ 15 | build 16 | 17 | # misc 18 | .DS_Store 19 | *.pem 20 | 21 | # debug 22 | npm-debug.log* 23 | .pnpm-debug.log* 24 | npm-debug.* 25 | 26 | # local env files 27 | .env.local 28 | .env.development.local 29 | .env.test.local 30 | .env.production.local 31 | 32 | # turbo 33 | .turbo 34 | 35 | # for build 36 | dist 37 | esm 38 | 39 | # graph 40 | graph/ 41 | 42 | # react-native 43 | expo-env.d.ts 44 | .expo/ 45 | *.jks 46 | *.p8 47 | *.p12 48 | *.key 49 | *.mobileprovision 50 | *.orig.* 51 | web-build/ 52 | 53 | # macOS 54 | .DS_Store 55 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | pnpm lint-staged 2 | -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.{ts,tsx}": ["prettier --write --ignore-unknown"] 3 | } 4 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | prefer-workspace-packages=true 2 | enable-pre-post-scripts=true 3 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v22.14.0 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # transforms testfixtures 2 | packages/codemods/src/transforms/testfixtures/** -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "esbenp.prettier-vscode", 5 | "antfu.pnpm-catalog-lens", 6 | "unifiedjs.vscode-mdx" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "editor.formatOnSave": true, 4 | "editor.codeActionsOnSave": { 5 | "source.fixAll.eslint": "explicit" 6 | }, 7 | "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact", "mdx"], 8 | "eslint.workingDirectories": [{ "mode": "auto" }], 9 | "vitest.disableWorkspaceWarning": true 10 | } 11 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | graph.suspensive.org -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Viva Republica, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /assets/logo_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/assets/logo_background.png -------------------------------------------------------------------------------- /assets/logo_background_star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/assets/logo_background_star.png -------------------------------------------------------------------------------- /assets/logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/assets/logo_dark.png -------------------------------------------------------------------------------- /configs/eslint-config/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @suspensive/eslint-config 2 | 3 | ## 0.0.1 4 | 5 | ### Patch Changes 6 | 7 | - [#1497](https://github.com/toss/suspensive/pull/1497) [`e400035`](https://github.com/toss/suspensive/commit/e4000352b7d3e42f0164983cca2bcde9fd24751c) Thanks [@kangju2000](https://github.com/kangju2000)! - chore: improve JSR imports sync with consistent dependency formatting 8 | -------------------------------------------------------------------------------- /configs/eslint-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@suspensive/eslint-config", 3 | "version": "0.0.1", 4 | "private": true, 5 | "license": "MIT", 6 | "author": "Jonghyeon Ko ", 7 | "type": "module", 8 | "main": "index.js", 9 | "module": "index.js", 10 | "scripts": { 11 | "clean": "rimraf ./dist ./coverage ./node_modules" 12 | }, 13 | "dependencies": { 14 | "@cspell/eslint-plugin": "^8.19.2", 15 | "@eslint-react/eslint-plugin": "^1.48.4", 16 | "@next/eslint-plugin-next": "catalog:", 17 | "@vitest/eslint-plugin": "^1.1.43", 18 | "eslint-config-prettier": "^10.1.2", 19 | "eslint-plugin-import": "^2.31.0", 20 | "eslint-plugin-jest-dom": "^5.5.0", 21 | "eslint-plugin-jsdoc": "^50.6.9", 22 | "eslint-plugin-mdx": "^3.4.1", 23 | "eslint-plugin-prettier": "^5.2.6", 24 | "eslint-plugin-react-hooks": "6.0.0-rc.1", 25 | "typescript-eslint": "^8.31.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /configs/tsconfig/base.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Default", 4 | "compilerOptions": { 5 | "composite": false, 6 | "declaration": true, 7 | "declarationMap": true, 8 | "esModuleInterop": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "inlineSources": false, 11 | "isolatedModules": true, 12 | "moduleResolution": "node", 13 | "noUnusedLocals": false, 14 | "noUnusedParameters": false, 15 | "preserveWatchOutput": true, 16 | "skipLibCheck": true, 17 | "strict": true, 18 | "resolveJsonModule": true 19 | }, 20 | "exclude": ["dist", "esm", "build", "node_modules"] 21 | } 22 | -------------------------------------------------------------------------------- /configs/tsconfig/nextjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Next.js", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "target": "es5", 7 | "lib": ["dom", "dom.iterable", "esnext"], 8 | "skipLibCheck": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "noEmit": true, 12 | "incremental": true, 13 | "esModuleInterop": true, 14 | "module": "esnext", 15 | "resolveJsonModule": true, 16 | "isolatedModules": true, 17 | "jsx": "preserve" 18 | }, 19 | "include": ["src", "next-env.d.ts"], 20 | "exclude": ["node_modules"] 21 | } 22 | -------------------------------------------------------------------------------- /configs/tsconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@suspensive/tsconfig", 3 | "version": "0.0.0-development", 4 | "private": true, 5 | "author": "Jonghyeon Ko ", 6 | "files": [ 7 | "base.json", 8 | "nextjs.json", 9 | "react-library.json" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /configs/tsconfig/react-library.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "React Library", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "jsx": "react-jsx", 7 | "lib": ["DOM", "ES2015"], 8 | "module": "ESNext", 9 | "target": "es6" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /configs/tsup/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import { fileURLToPath } from 'url' 3 | import { suspensiveTypeScriptConfig } from '@suspensive/eslint-config' 4 | 5 | export default [ 6 | ...suspensiveTypeScriptConfig, 7 | { 8 | ignores: ['dist'], 9 | languageOptions: { 10 | parserOptions: { 11 | tsconfigRootDir: path.dirname(fileURLToPath(import.meta.url)), 12 | project: './tsconfig.json', 13 | }, 14 | }, 15 | }, 16 | ] 17 | -------------------------------------------------------------------------------- /configs/tsup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@suspensive/tsup", 3 | "version": "0.0.0", 4 | "private": true, 5 | "author": "Jonghyeon Ko ", 6 | "sideEffects": false, 7 | "type": "module", 8 | "exports": { 9 | ".": { 10 | "import": { 11 | "types": "./dist/index.d.ts", 12 | "default": "./dist/index.js" 13 | }, 14 | "require": { 15 | "types": "./dist/index.d.cts", 16 | "default": "./dist/index.cjs" 17 | } 18 | }, 19 | "./package.json": "./package.json" 20 | }, 21 | "main": "dist/index.cjs", 22 | "module": "dist/index.js", 23 | "types": "dist/index.d.ts", 24 | "scripts": { 25 | "build": "tsup", 26 | "ci:attw": "attw --pack", 27 | "ci:eslint": "eslint \"**/*.{ts,tsx,cts,mts}\"", 28 | "ci:publint": "publint --strict", 29 | "ci:type": "tsc --noEmit", 30 | "clean": "rimraf ./dist ./coverage ./node_modules", 31 | "prepack": "pnpm run build" 32 | }, 33 | "devDependencies": { 34 | "@suspensive/eslint-config": "workspace:*", 35 | "@suspensive/tsconfig": "workspace:*" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /configs/tsup/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { Options } from 'tsup' 2 | 3 | export const options: Options = { 4 | banner: { js: '"use client"' }, 5 | format: ['cjs', 'esm'], 6 | target: ['chrome51', 'firefox53', 'edge18', 'safari11', 'ios11', 'opera38', 'es6', 'node14'], 7 | entry: ['src/*.{ts,tsx}', '!**/*.{spec,test,test-d}.*'], 8 | outDir: 'dist', 9 | sourcemap: true, 10 | dts: true, 11 | } 12 | 13 | export const scriptOptions: Options = { 14 | format: 'cjs', 15 | target: ['node18'], 16 | entry: ['src/bin/*.{ts,tsx}', '!**/*.{spec,test,test-d}.*'], 17 | outDir: 'dist/bin', 18 | } 19 | -------------------------------------------------------------------------------- /configs/tsup/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@suspensive/tsconfig/base.json", 3 | "include": [".", "./eslint.config.mjs"], 4 | "exclude": ["dist", "node_modules"], 5 | "compilerOptions": { 6 | "module": "NodeNext", 7 | "moduleResolution": "NodeNext", 8 | "outDir": "dist" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /configs/tsup/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | import { options } from './src/index.js' 3 | 4 | export default defineConfig(options) 5 | -------------------------------------------------------------------------------- /docs/suspensive.org/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env*.local 29 | 30 | # vercel 31 | .vercel 32 | 33 | # typescript 34 | *.tsbuildinfo 35 | next-env.d.ts 36 | 37 | _pagefind/ 38 | -------------------------------------------------------------------------------- /docs/suspensive.org/README.md: -------------------------------------------------------------------------------- 1 | # [Suspensive.org](https://suspensive.org) 2 | 3 | The official website for [Suspensive](https://github.com/toss/suspensive). 4 | 5 | To develop locally, clone this repository and run the following command to start 6 | the local dev server: 7 | 8 | ```bash 9 | pnpm 10 | pnpm 4000 11 | ``` 12 | 13 | And visit `localhost:4000` to preview your changes. 14 | -------------------------------------------------------------------------------- /docs/suspensive.org/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import { fileURLToPath } from 'url' 3 | import { 4 | suspensiveMDXConfig, 5 | suspensiveNextTypeScriptConfig, 6 | } from '@suspensive/eslint-config' 7 | 8 | export default [ 9 | ...suspensiveNextTypeScriptConfig, 10 | ...suspensiveMDXConfig, 11 | { 12 | languageOptions: { 13 | parserOptions: { 14 | tsconfigRootDir: path.dirname(fileURLToPath(import.meta.url)), 15 | project: './tsconfig.json', 16 | extraFileExtensions: ['.mdx'], 17 | }, 18 | }, 19 | }, 20 | ] 21 | -------------------------------------------------------------------------------- /docs/suspensive.org/next.config.mjs: -------------------------------------------------------------------------------- 1 | import { recmaCodeHike, remarkCodeHike } from 'codehike/mdx' 2 | import nextra from 'nextra' 3 | import { remarkSandpack } from 'remark-sandpack' 4 | 5 | /** @type {import('codehike/mdx').CodeHikeConfig} */ 6 | const chConfig = { 7 | syntaxHighlighting: { 8 | theme: 'github-dark', 9 | }, 10 | } 11 | 12 | const withNextra = nextra({ 13 | defaultShowCopyCode: true, 14 | latex: true, 15 | mdxOptions: { 16 | remarkPlugins: [[remarkCodeHike, chConfig], remarkSandpack], 17 | recmaPlugins: [[recmaCodeHike, chConfig]], 18 | rehypePlugins: [], 19 | rehypePrettyCodeOptions: { 20 | theme: 'github-dark-default', 21 | keepBackground: false, 22 | }, 23 | }, 24 | search: { 25 | codeblocks: true, 26 | }, 27 | codeHighlight: true, 28 | readingTime: true, 29 | }) 30 | 31 | /** 32 | * @type {import('next').NextConfig} 33 | */ 34 | export default withNextra({ 35 | reactStrictMode: true, 36 | i18n: { 37 | locales: ['en', 'ko'], 38 | defaultLocale: 'en', 39 | }, 40 | }) 41 | -------------------------------------------------------------------------------- /docs/suspensive.org/postcss.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss').Postcss} */ 2 | export default { 3 | plugins: { 4 | '@tailwindcss/postcss': {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /docs/suspensive.org/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | import rootConfig from '../../prettier.config.mjs' 2 | 3 | /** @type {import("prettier").Config} */ 4 | export default { 5 | ...rootConfig, 6 | plugins: ['prettier-plugin-tailwindcss'], 7 | printWidth: 80, 8 | } 9 | -------------------------------------------------------------------------------- /docs/suspensive.org/public/img/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/docs/suspensive.org/public/img/banner.png -------------------------------------------------------------------------------- /docs/suspensive.org/public/img/errorBoundary-shouldcatch-prop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/docs/suspensive.org/public/img/errorBoundary-shouldcatch-prop.png -------------------------------------------------------------------------------- /docs/suspensive.org/public/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/docs/suspensive.org/public/img/favicon.ico -------------------------------------------------------------------------------- /docs/suspensive.org/public/img/homepage_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/docs/suspensive.org/public/img/homepage_logo.png -------------------------------------------------------------------------------- /docs/suspensive.org/public/img/icons/check.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/suspensive.org/public/img/icons/content_copy.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/suspensive.org/public/img/logo_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/docs/suspensive.org/public/img/logo_background.png -------------------------------------------------------------------------------- /docs/suspensive.org/public/img/logo_background_star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/docs/suspensive.org/public/img/logo_background_star.png -------------------------------------------------------------------------------- /docs/suspensive.org/public/img/logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/docs/suspensive.org/public/img/logo_dark.png -------------------------------------------------------------------------------- /docs/suspensive.org/public/img/logo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/docs/suspensive.org/public/img/logo_light.png -------------------------------------------------------------------------------- /docs/suspensive.org/public/img/logo_not_cropped.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/docs/suspensive.org/public/img/logo_not_cropped.png -------------------------------------------------------------------------------- /docs/suspensive.org/public/img/react-query_community-resources.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/docs/suspensive.org/public/img/react-query_community-resources.png -------------------------------------------------------------------------------- /docs/suspensive.org/public/img/react-query_private-class-fields-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/docs/suspensive.org/public/img/react-query_private-class-fields-error.png -------------------------------------------------------------------------------- /docs/suspensive.org/public/img/react-query_private-class-fields-tkdodo-comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/docs/suspensive.org/public/img/react-query_private-class-fields-tkdodo-comment.png -------------------------------------------------------------------------------- /docs/suspensive.org/public/img/suspense-in-ssr-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/docs/suspensive.org/public/img/suspense-in-ssr-error.png -------------------------------------------------------------------------------- /docs/suspensive.org/src/app/[lang]/[[...mdxPath]]/FadeIn.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { motion } from 'motion/react' 4 | import type { ReactNode } from 'react' 5 | 6 | export const FadeIn = ({ children }: { children: ReactNode }) => ( 7 | 8 | {children} 9 | 10 | ) 11 | -------------------------------------------------------------------------------- /docs/suspensive.org/src/app/[lang]/[[...mdxPath]]/MDXContent.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import type { $NextraMetadata, Heading } from 'nextra' 4 | import type { ReactNode } from 'react' 5 | import { FadeIn } from './FadeIn' 6 | import { useMDXComponents } from '@/mdx-components' 7 | 8 | type MDXContentProps = { 9 | toc: Array 10 | metadata: $NextraMetadata 11 | isIndexPage: boolean 12 | mdxPath: string[] 13 | children: ReactNode 14 | } 15 | 16 | export function MDXContent({ 17 | toc, 18 | metadata, 19 | isIndexPage, 20 | mdxPath, 21 | children, 22 | }: MDXContentProps) { 23 | const { wrapper: Wrapper } = useMDXComponents() 24 | 25 | return ( 26 | 27 | {isIndexPage ? ( 28 | children 29 | ) : ( 30 | {children} 31 | )} 32 | 33 | ) 34 | } 35 | -------------------------------------------------------------------------------- /docs/suspensive.org/src/app/[lang]/_components/Logo.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { motion } from 'motion/react' 4 | import Image from 'next/image' 5 | 6 | export const Logo = () => { 7 | return ( 8 | 13 | 14 | suspensive logo 20 | 21 |
22 | Suspensive 23 | v3 24 |
25 |
26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /docs/suspensive.org/src/app/[lang]/not-found.ts: -------------------------------------------------------------------------------- 1 | export { NotFoundPage as default } from 'nextra-theme-docs' 2 | -------------------------------------------------------------------------------- /docs/suspensive.org/src/app/[lang]/styles.css: -------------------------------------------------------------------------------- 1 | @import 'tailwindcss'; 2 | @import 'nextra-theme-docs/style.css'; 3 | 4 | .scrollbar-none { 5 | -ms-overflow-style: none; /* IE and Edge */ 6 | scrollbar-width: none; /* Firefox */ 7 | } 8 | .scrollbar-none::-webkit-scrollbar { 9 | display: none; /* Chrome, Safari, Opera*/ 10 | } 11 | 12 | body { 13 | background-color: #0c0c0c; 14 | } 15 | -------------------------------------------------------------------------------- /docs/suspensive.org/src/app/_dictionaries/en.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from 'nextra-theme-docs' 2 | 3 | export default { 4 | toc: { 5 | title: 'On This Page', 6 | backToTop: 'Scroll to top', 7 | }, 8 | search: { placeholder: 'Search Documentation...' }, 9 | footer: { 10 | editLink: 'Edit this page on GitHub', 11 | }, 12 | banner: ( 13 | 14 | 👀 Check out the changes in Suspensive v3.{' '} 15 | read more 16 | 17 | ), 18 | lastUpdated: 'Last updated on', 19 | editPage: 'Edit this page on GitHub', 20 | } 21 | -------------------------------------------------------------------------------- /docs/suspensive.org/src/app/_dictionaries/get-dictionary.ts: -------------------------------------------------------------------------------- 1 | import 'server-only' 2 | import type En from './en' 3 | 4 | // We enumerate all dictionaries here for better linting and TypeScript support 5 | // We also get the default import for cleaner types 6 | const dictionaries = { 7 | en: () => import('./en'), 8 | ko: () => import('./ko'), 9 | } as const satisfies Record Promise<{ default: typeof En }>> 10 | 11 | export const getDictionary = async ( 12 | locale: keyof typeof dictionaries 13 | ): Promise => (await dictionaries[locale]()).default 14 | 15 | export const getDirection = (locale: keyof typeof dictionaries) => { 16 | switch (locale) { 17 | case 'en': 18 | case 'ko': 19 | default: 20 | return 'ltr' as const 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /docs/suspensive.org/src/app/_dictionaries/ko.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from 'nextra-theme-docs' 2 | import type En from './en' 3 | 4 | export default { 5 | toc: { 6 | title: '이 페이지', 7 | backToTop: '맨 위로', 8 | }, 9 | search: { placeholder: '검색어를 입력하세요...' }, 10 | footer: { 11 | editLink: 'Edit this page on GitHub', 12 | }, 13 | banner: ( 14 | 15 | 👀 Suspensive v3에서의 변경을 확인하세요.{' '} 16 | 더보기 17 | 18 | ), 19 | lastUpdated: '수정된 날짜:', 20 | editPage: 'GitHub에서 이 페이지 수정하기', 21 | } satisfies typeof En 22 | -------------------------------------------------------------------------------- /docs/suspensive.org/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toss/suspensive/5f139f94e49bf77b0fcd9d98cc4dec71b35db61c/docs/suspensive.org/src/app/favicon.ico -------------------------------------------------------------------------------- /docs/suspensive.org/src/components/Callout.tsx: -------------------------------------------------------------------------------- 1 | import { Callout as NextraCallout } from 'nextra/components' 2 | import type { ComponentPropsWithoutRef } from 'react' 3 | 4 | type CalloutProps = Omit< 5 | ComponentPropsWithoutRef, 6 | 'type' 7 | > & { 8 | type: 9 | | 'deprecated' 10 | | 'experimental' 11 | | ComponentPropsWithoutRef['type'] 12 | } 13 | 14 | export const Callout = ({ type, ...props }: CalloutProps) => { 15 | const definedType = 16 | type === 'deprecated' ? 'error' : type === 'experimental' ? 'warning' : type 17 | 18 | return 19 | } 20 | -------------------------------------------------------------------------------- /docs/suspensive.org/src/components/GlowEffect.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { motion } from 'motion/react' 4 | import { useMemo } from 'react' 5 | 6 | export function GlowEffect() { 7 | const background = useMemo( 8 | () => 9 | ['#FF5733', '#33FF57', '#3357FF', '#F1C40F'].map( 10 | (color, index, colors) => 11 | `conic-gradient(from 0deg at 50% 50%, ${color} 0%, ${colors[(index + 1) % colors.length]} 50%, ${color} 100%)` 12 | ), 13 | [] 14 | ) 15 | return ( 16 | 37 | ) 38 | } 39 | -------------------------------------------------------------------------------- /docs/suspensive.org/src/components/Sandpack/ConsoleCounterButton.tsx: -------------------------------------------------------------------------------- 1 | import { ConsoleIcon, RoundedButton } from '@codesandbox/sandpack-react' 2 | 3 | interface ConsoleCounterButtonProps { 4 | onClick: () => void 5 | counter: number 6 | } 7 | 8 | export const ConsoleCounterButton = ({ 9 | onClick, 10 | counter, 11 | }: ConsoleCounterButtonProps) => { 12 | return ( 13 | 14 | 15 | {counter > 0 && ( 16 | 17 | {counter} 18 | 19 | )} 20 | 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /docs/suspensive.org/src/components/Sandpack/ErrorOverlay.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ErrorOverlay as SandpackErrorOverlay, 3 | useErrorMessage, 4 | } from '@codesandbox/sandpack-react' 5 | 6 | export const ErrorOverlay = () => { 7 | const errorMessage = useErrorMessage() 8 | 9 | // https://github.com/codesandbox/sandpack/blob/main/sandpack-react/src/components/common/ErrorOverlay.tsx#L54-L55 10 | const isSandpackBundlerError = errorMessage?.startsWith('[sandpack-client]') 11 | const privateDependencyError = errorMessage?.includes( 12 | 'NPM_REGISTRY_UNAUTHENTICATED_REQUEST' 13 | ) 14 | 15 | if (privateDependencyError || (isSandpackBundlerError && errorMessage)) { 16 | return 17 | } 18 | 19 | return null 20 | } 21 | -------------------------------------------------------------------------------- /docs/suspensive.org/src/components/Sandpack/SandPackCSS.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { getSandpackCssText } from '@codesandbox/sandpack-react' 4 | 5 | export const SandPackCSS = () => { 6 | return ( 7 |