From b324a9b87721934154c8b1c3d4447e3719c0a56b Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Sun, 8 Jan 2023 22:28:07 +1100 Subject: [PATCH 01/37] feat(svelte-query): Svelte Query Adapter for TanStack Query (#4768) * feat: svelte-query adapter * add examples * add @testing-library/svelte and svelte-jester * add transform for testing svelte components * re-export @tanstack/core core * add a few initial test * delete tests in examples * use ^ in dependencies * delete and gitignore .vscode * rename basic-typescript to basic * add basic example to ci.json * remove transform from global preset * update version * don't gitignore lib directory in svelte examples * fix build files location in package.json * chore: prettier formatting * add missing state * chore: fix eslint errors * add context * unsubscribe * add missing export * use svelte context * update version * update examples to use context * release: v4.14.5 * remove onMount * add onMount to setQueryClient * remove unneeded exports * Add basic svelte docs overview * Add SvelteKit 1.0 example Uses the data from the simple example * Edit nodeResolve settings * More rollup and babel tweaks Seems to be working * Try svelte plugin options * Separate out svelte config * Switch to svelte-package * Reset rollup config * Output to ./build * Use vitest in svelte-query * Fix test imports * Avoid transpiling TS during typecheck * Fix vitest command * More vitest migration work * Minor fixes to tests * Rename file to types.d.ts * Replace setQueryContext with QueryClientProvider * Replace tabs with spaces for repo consistency * Update examples to sveltekit 1.0 * Implement Hydrate component * Add playground example Rewrite of the react example * Start adding star-wars example * Add films and film pages * Finish star-wars example * Rename store functions with create prefix * Add correct favicons * Reorder some files in svelte-query * Undo rollup.config.ts changes * Add new createQuery and createMutation tests * More descriptive test name * Misc fixes from feedback - Max TS 4.7.4 - Move root package.json dependencies - Use object syntax - Use test:jest script (for now) - Remove sveltekit autogenerated files * Fix pnpm-lock * Specify svelte-package source, update TS to 4.7.4 * Remove unnecessary packages in examples * Sync pnpm-lock * Reset pnpm-lock to upstream * Run pnpm install * Remove svelte-query from root tsconfg Needs to be run from its own svelte-check package... sorry * Run prettier, remove unused import * Run prettier on svelte files Requires prettier-plugin-svelte to run * Prettier for changed files * Fix cipublish from svelte-query * rimraf to remove build/lib/package.json * Run svelte-kit sync before vitest * Add files field to package.json * Add types field to package.json * Bump svelte-query version to 4.20.0 In case this fixes the CI issue * Add path alias to vitest * Update vitest to 0.26 Changes module resolution? * More CI improvements * Remove --parallel from pnpm scripts * Remove unused dependency * Add eslint settings Thanks @rivo420 * Add coverage report Co-authored-by: DeAndre Johnson Co-authored-by: Dominik Dorfmeister RELEASE_ALL --- .codesandbox/ci.json | 2 +- .prettierignore | 1 + babel.config.js | 2 +- docs/config.json | 2 +- docs/svelte/overview.md | 67 +- examples/svelte/auto-refetching/.gitignore | 9 + examples/svelte/auto-refetching/README.md | 38 + examples/svelte/auto-refetching/package.json | 25 + examples/svelte/auto-refetching/src/app.css | 81 + examples/svelte/auto-refetching/src/app.d.ts | 9 + examples/svelte/auto-refetching/src/app.html | 12 + .../auto-refetching/src/routes/+layout.svelte | 12 + .../auto-refetching/src/routes/+page.svelte | 101 + .../src/routes/api/data/+server.ts | 19 + .../auto-refetching/static/emblem-light.svg | 13 + .../svelte/auto-refetching/svelte.config.js | 15 + examples/svelte/auto-refetching/tsconfig.json | 17 + .../svelte/auto-refetching/vite.config.ts | 8 + examples/svelte/basic/.gitignore | 24 + examples/svelte/basic/README.md | 48 + examples/svelte/basic/index.html | 13 + examples/svelte/basic/package.json | 25 + examples/svelte/basic/public/emblem-light.svg | 13 + examples/svelte/basic/src/App.svelte | 13 + examples/svelte/basic/src/app.css | 81 + examples/svelte/basic/src/assets/svelte.svg | 1 + .../svelte/basic/src/lib/BasicQuery.svelte | 15 + examples/svelte/basic/src/lib/Post.svelte | 34 + examples/svelte/basic/src/lib/Posts.svelte | 61 + examples/svelte/basic/src/lib/data.ts | 16 + examples/svelte/basic/src/main.ts | 8 + examples/svelte/basic/src/vite-env.d.ts | 2 + examples/svelte/basic/svelte.config.js | 7 + examples/svelte/basic/tsconfig.json | 21 + examples/svelte/basic/tsconfig.node.json | 8 + examples/svelte/basic/vite.config.ts | 7 + examples/svelte/hydration/.gitignore | 9 + examples/svelte/hydration/README.md | 38 + examples/svelte/hydration/package.json | 25 + examples/svelte/hydration/src/app.css | 81 + examples/svelte/hydration/src/app.d.ts | 9 + examples/svelte/hydration/src/app.html | 11 + examples/svelte/hydration/src/lib/Post.svelte | 34 + .../svelte/hydration/src/lib/Posts.svelte | 61 + examples/svelte/hydration/src/lib/data.ts | 16 + examples/svelte/hydration/src/lib/store.ts | 4 + .../hydration/src/routes/+layout.svelte | 19 + .../svelte/hydration/src/routes/+page.svelte | 31 + examples/svelte/hydration/src/routes/+page.ts | 16 + .../hydration/src/routes/api/data/+server.ts | 29 + .../svelte/hydration/static/emblem-light.svg | 13 + examples/svelte/hydration/svelte.config.js | 15 + examples/svelte/hydration/tsconfig.json | 17 + examples/svelte/hydration/vite.config.ts | 8 + examples/svelte/infinite-loadmore/.gitignore | 24 + examples/svelte/infinite-loadmore/README.md | 48 + examples/svelte/infinite-loadmore/index.html | 13 + .../svelte/infinite-loadmore/package.json | 25 + .../infinite-loadmore/public/emblem-light.svg | 13 + .../svelte/infinite-loadmore/src/App.svelte | 13 + examples/svelte/infinite-loadmore/src/app.css | 81 + .../infinite-loadmore/src/assets/svelte.svg | 1 + .../infinite-loadmore/src/lib/LoadMore.svelte | 66 + examples/svelte/infinite-loadmore/src/main.ts | 8 + .../infinite-loadmore/src/vite-env.d.ts | 2 + .../svelte/infinite-loadmore/svelte.config.js | 7 + .../svelte/infinite-loadmore/tsconfig.json | 21 + .../infinite-loadmore/tsconfig.node.json | 8 + .../svelte/infinite-loadmore/vite.config.ts | 7 + .../optimistic-updates-typescript/.gitignore | 9 + .../optimistic-updates-typescript/README.md | 38 + .../package.json | 25 + .../optimistic-updates-typescript/src/app.css | 81 + .../src/app.d.ts | 9 + .../src/app.html | 12 + .../src/routes/+layout.svelte | 12 + .../src/routes/+page.svelte | 129 ++ .../src/routes/api/data/+server.ts | 29 + .../static/emblem-light.svg | 13 + .../svelte.config.js | 15 + .../tsconfig.json | 17 + .../vite.config.ts | 8 + examples/svelte/playground/.gitignore | 9 + examples/svelte/playground/README.md | 8 + examples/svelte/playground/package.json | 24 + examples/svelte/playground/src/app.css | 11 + examples/svelte/playground/src/app.d.ts | 9 + examples/svelte/playground/src/app.html | 12 + examples/svelte/playground/src/lib/stores.ts | 23 + .../playground/src/routes/+layout.svelte | 16 + .../svelte/playground/src/routes/+page.svelte | 81 + .../playground/src/routes/AddTodo.svelte | 57 + .../svelte/playground/src/routes/App.svelte | 42 + .../playground/src/routes/EditTodo.svelte | 118 ++ .../svelte/playground/src/routes/Todos.svelte | 71 + .../svelte/playground/static/emblem-light.svg | 13 + examples/svelte/playground/svelte.config.js | 13 + examples/svelte/playground/tsconfig.json | 13 + examples/svelte/playground/vite.config.ts | 8 + examples/svelte/simple/.gitignore | 24 + examples/svelte/simple/README.md | 48 + examples/svelte/simple/index.html | 13 + examples/svelte/simple/package.json | 25 + .../svelte/simple/public/emblem-light.svg | 13 + examples/svelte/simple/src/App.svelte | 12 + examples/svelte/simple/src/app.css | 81 + examples/svelte/simple/src/assets/svelte.svg | 1 + examples/svelte/simple/src/lib/Simple.svelte | 41 + examples/svelte/simple/src/main.ts | 8 + examples/svelte/simple/src/vite-env.d.ts | 2 + examples/svelte/simple/svelte.config.js | 7 + examples/svelte/simple/tsconfig.json | 21 + examples/svelte/simple/tsconfig.node.json | 8 + examples/svelte/simple/vite.config.ts | 7 + examples/svelte/star-wars/.gitignore | 9 + examples/svelte/star-wars/README.md | 8 + examples/svelte/star-wars/package.json | 27 + examples/svelte/star-wars/postcss.config.cjs | 3 + examples/svelte/star-wars/src/app.css | 18 + examples/svelte/star-wars/src/app.d.ts | 9 + examples/svelte/star-wars/src/app.html | 12 + .../star-wars/src/routes/+layout.svelte | 21 + .../svelte/star-wars/src/routes/+page.svelte | 32 + .../src/routes/characters/+page.svelte | 36 + .../characters/[characterId]/+page.svelte | 77 + .../routes/characters/[characterId]/+page.ts | 5 + .../characters/[characterId]/Film.svelte | 23 + .../characters/[characterId]/Homeworld.svelte | 21 + .../star-wars/src/routes/films/+page.svelte | 41 + .../src/routes/films/[filmId]/+page.svelte | 41 + .../src/routes/films/[filmId]/+page.ts | 5 + .../routes/films/[filmId]/Character.svelte | 23 + .../svelte/star-wars/static/emblem-light.svg | 13 + examples/svelte/star-wars/svelte.config.js | 13 + examples/svelte/star-wars/tailwind.config.cjs | 11 + examples/svelte/star-wars/tsconfig.json | 13 + examples/svelte/star-wars/vite.config.ts | 8 + package.json | 13 +- packages/svelte-query/.eslintrc | 25 + packages/svelte-query/.gitignore | 9 + packages/svelte-query/package.json | 54 + .../src/__tests__/CreateMutation.svelte | 13 + .../src/__tests__/CreateQuery.svelte | 23 + .../src/__tests__/createMutation.test.ts | 22 + .../src/__tests__/createQuery.test.ts | 28 + packages/svelte-query/src/__tests__/utils.ts | 72 + packages/svelte-query/src/lib/Hydrate.svelte | 11 + .../src/lib/QueryClientProvider.svelte | 19 + packages/svelte-query/src/lib/context.ts | 21 + .../svelte-query/src/lib/createBaseQuery.ts | 76 + .../src/lib/createInfiniteQuery.ts | 103 + .../svelte-query/src/lib/createMutation.ts | 110 + .../svelte-query/src/lib/createQueries.ts | 178 ++ packages/svelte-query/src/lib/createQuery.ts | 143 ++ packages/svelte-query/src/lib/index.ts | 17 + packages/svelte-query/src/lib/types.ts | 146 ++ packages/svelte-query/src/lib/useHydrate.ts | 14 + .../svelte-query/src/lib/useIsFetching.ts | 41 + .../svelte-query/src/lib/useIsMutating.ts | 41 + .../svelte-query/src/lib/useQueryClient.ts | 7 + packages/svelte-query/static/emblem-light.svg | 13 + packages/svelte-query/svelte.config.js | 16 + packages/svelte-query/tsconfig.json | 14 + packages/svelte-query/vite.config.ts | 22 + packages/svelte-query/vitest.setup.ts | 4 + pnpm-lock.yaml | 1831 ++++++++++++++++- pnpm-workspace.yaml | 1 + scripts/config.ts | 5 + scripts/publish.ts | 2 + 169 files changed, 6295 insertions(+), 107 deletions(-) create mode 100644 .prettierignore create mode 100644 examples/svelte/auto-refetching/.gitignore create mode 100644 examples/svelte/auto-refetching/README.md create mode 100644 examples/svelte/auto-refetching/package.json create mode 100644 examples/svelte/auto-refetching/src/app.css create mode 100644 examples/svelte/auto-refetching/src/app.d.ts create mode 100644 examples/svelte/auto-refetching/src/app.html create mode 100644 examples/svelte/auto-refetching/src/routes/+layout.svelte create mode 100644 examples/svelte/auto-refetching/src/routes/+page.svelte create mode 100644 examples/svelte/auto-refetching/src/routes/api/data/+server.ts create mode 100644 examples/svelte/auto-refetching/static/emblem-light.svg create mode 100644 examples/svelte/auto-refetching/svelte.config.js create mode 100644 examples/svelte/auto-refetching/tsconfig.json create mode 100644 examples/svelte/auto-refetching/vite.config.ts create mode 100644 examples/svelte/basic/.gitignore create mode 100644 examples/svelte/basic/README.md create mode 100644 examples/svelte/basic/index.html create mode 100644 examples/svelte/basic/package.json create mode 100644 examples/svelte/basic/public/emblem-light.svg create mode 100644 examples/svelte/basic/src/App.svelte create mode 100644 examples/svelte/basic/src/app.css create mode 100644 examples/svelte/basic/src/assets/svelte.svg create mode 100644 examples/svelte/basic/src/lib/BasicQuery.svelte create mode 100644 examples/svelte/basic/src/lib/Post.svelte create mode 100644 examples/svelte/basic/src/lib/Posts.svelte create mode 100644 examples/svelte/basic/src/lib/data.ts create mode 100644 examples/svelte/basic/src/main.ts create mode 100644 examples/svelte/basic/src/vite-env.d.ts create mode 100644 examples/svelte/basic/svelte.config.js create mode 100644 examples/svelte/basic/tsconfig.json create mode 100644 examples/svelte/basic/tsconfig.node.json create mode 100644 examples/svelte/basic/vite.config.ts create mode 100644 examples/svelte/hydration/.gitignore create mode 100644 examples/svelte/hydration/README.md create mode 100644 examples/svelte/hydration/package.json create mode 100644 examples/svelte/hydration/src/app.css create mode 100644 examples/svelte/hydration/src/app.d.ts create mode 100644 examples/svelte/hydration/src/app.html create mode 100644 examples/svelte/hydration/src/lib/Post.svelte create mode 100644 examples/svelte/hydration/src/lib/Posts.svelte create mode 100644 examples/svelte/hydration/src/lib/data.ts create mode 100644 examples/svelte/hydration/src/lib/store.ts create mode 100644 examples/svelte/hydration/src/routes/+layout.svelte create mode 100644 examples/svelte/hydration/src/routes/+page.svelte create mode 100644 examples/svelte/hydration/src/routes/+page.ts create mode 100644 examples/svelte/hydration/src/routes/api/data/+server.ts create mode 100644 examples/svelte/hydration/static/emblem-light.svg create mode 100644 examples/svelte/hydration/svelte.config.js create mode 100644 examples/svelte/hydration/tsconfig.json create mode 100644 examples/svelte/hydration/vite.config.ts create mode 100644 examples/svelte/infinite-loadmore/.gitignore create mode 100644 examples/svelte/infinite-loadmore/README.md create mode 100644 examples/svelte/infinite-loadmore/index.html create mode 100644 examples/svelte/infinite-loadmore/package.json create mode 100644 examples/svelte/infinite-loadmore/public/emblem-light.svg create mode 100644 examples/svelte/infinite-loadmore/src/App.svelte create mode 100644 examples/svelte/infinite-loadmore/src/app.css create mode 100644 examples/svelte/infinite-loadmore/src/assets/svelte.svg create mode 100644 examples/svelte/infinite-loadmore/src/lib/LoadMore.svelte create mode 100644 examples/svelte/infinite-loadmore/src/main.ts create mode 100644 examples/svelte/infinite-loadmore/src/vite-env.d.ts create mode 100644 examples/svelte/infinite-loadmore/svelte.config.js create mode 100644 examples/svelte/infinite-loadmore/tsconfig.json create mode 100644 examples/svelte/infinite-loadmore/tsconfig.node.json create mode 100644 examples/svelte/infinite-loadmore/vite.config.ts create mode 100644 examples/svelte/optimistic-updates-typescript/.gitignore create mode 100644 examples/svelte/optimistic-updates-typescript/README.md create mode 100644 examples/svelte/optimistic-updates-typescript/package.json create mode 100644 examples/svelte/optimistic-updates-typescript/src/app.css create mode 100644 examples/svelte/optimistic-updates-typescript/src/app.d.ts create mode 100644 examples/svelte/optimistic-updates-typescript/src/app.html create mode 100644 examples/svelte/optimistic-updates-typescript/src/routes/+layout.svelte create mode 100644 examples/svelte/optimistic-updates-typescript/src/routes/+page.svelte create mode 100644 examples/svelte/optimistic-updates-typescript/src/routes/api/data/+server.ts create mode 100644 examples/svelte/optimistic-updates-typescript/static/emblem-light.svg create mode 100644 examples/svelte/optimistic-updates-typescript/svelte.config.js create mode 100644 examples/svelte/optimistic-updates-typescript/tsconfig.json create mode 100644 examples/svelte/optimistic-updates-typescript/vite.config.ts create mode 100644 examples/svelte/playground/.gitignore create mode 100644 examples/svelte/playground/README.md create mode 100644 examples/svelte/playground/package.json create mode 100644 examples/svelte/playground/src/app.css create mode 100644 examples/svelte/playground/src/app.d.ts create mode 100644 examples/svelte/playground/src/app.html create mode 100644 examples/svelte/playground/src/lib/stores.ts create mode 100644 examples/svelte/playground/src/routes/+layout.svelte create mode 100644 examples/svelte/playground/src/routes/+page.svelte create mode 100644 examples/svelte/playground/src/routes/AddTodo.svelte create mode 100644 examples/svelte/playground/src/routes/App.svelte create mode 100644 examples/svelte/playground/src/routes/EditTodo.svelte create mode 100644 examples/svelte/playground/src/routes/Todos.svelte create mode 100644 examples/svelte/playground/static/emblem-light.svg create mode 100644 examples/svelte/playground/svelte.config.js create mode 100644 examples/svelte/playground/tsconfig.json create mode 100644 examples/svelte/playground/vite.config.ts create mode 100644 examples/svelte/simple/.gitignore create mode 100644 examples/svelte/simple/README.md create mode 100644 examples/svelte/simple/index.html create mode 100644 examples/svelte/simple/package.json create mode 100644 examples/svelte/simple/public/emblem-light.svg create mode 100644 examples/svelte/simple/src/App.svelte create mode 100644 examples/svelte/simple/src/app.css create mode 100644 examples/svelte/simple/src/assets/svelte.svg create mode 100644 examples/svelte/simple/src/lib/Simple.svelte create mode 100644 examples/svelte/simple/src/main.ts create mode 100644 examples/svelte/simple/src/vite-env.d.ts create mode 100644 examples/svelte/simple/svelte.config.js create mode 100644 examples/svelte/simple/tsconfig.json create mode 100644 examples/svelte/simple/tsconfig.node.json create mode 100644 examples/svelte/simple/vite.config.ts create mode 100644 examples/svelte/star-wars/.gitignore create mode 100644 examples/svelte/star-wars/README.md create mode 100644 examples/svelte/star-wars/package.json create mode 100644 examples/svelte/star-wars/postcss.config.cjs create mode 100644 examples/svelte/star-wars/src/app.css create mode 100644 examples/svelte/star-wars/src/app.d.ts create mode 100644 examples/svelte/star-wars/src/app.html create mode 100644 examples/svelte/star-wars/src/routes/+layout.svelte create mode 100644 examples/svelte/star-wars/src/routes/+page.svelte create mode 100644 examples/svelte/star-wars/src/routes/characters/+page.svelte create mode 100644 examples/svelte/star-wars/src/routes/characters/[characterId]/+page.svelte create mode 100644 examples/svelte/star-wars/src/routes/characters/[characterId]/+page.ts create mode 100644 examples/svelte/star-wars/src/routes/characters/[characterId]/Film.svelte create mode 100644 examples/svelte/star-wars/src/routes/characters/[characterId]/Homeworld.svelte create mode 100644 examples/svelte/star-wars/src/routes/films/+page.svelte create mode 100644 examples/svelte/star-wars/src/routes/films/[filmId]/+page.svelte create mode 100644 examples/svelte/star-wars/src/routes/films/[filmId]/+page.ts create mode 100644 examples/svelte/star-wars/src/routes/films/[filmId]/Character.svelte create mode 100644 examples/svelte/star-wars/static/emblem-light.svg create mode 100644 examples/svelte/star-wars/svelte.config.js create mode 100644 examples/svelte/star-wars/tailwind.config.cjs create mode 100644 examples/svelte/star-wars/tsconfig.json create mode 100644 examples/svelte/star-wars/vite.config.ts create mode 100644 packages/svelte-query/.eslintrc create mode 100644 packages/svelte-query/.gitignore create mode 100644 packages/svelte-query/package.json create mode 100644 packages/svelte-query/src/__tests__/CreateMutation.svelte create mode 100644 packages/svelte-query/src/__tests__/CreateQuery.svelte create mode 100644 packages/svelte-query/src/__tests__/createMutation.test.ts create mode 100644 packages/svelte-query/src/__tests__/createQuery.test.ts create mode 100644 packages/svelte-query/src/__tests__/utils.ts create mode 100644 packages/svelte-query/src/lib/Hydrate.svelte create mode 100644 packages/svelte-query/src/lib/QueryClientProvider.svelte create mode 100644 packages/svelte-query/src/lib/context.ts create mode 100644 packages/svelte-query/src/lib/createBaseQuery.ts create mode 100644 packages/svelte-query/src/lib/createInfiniteQuery.ts create mode 100644 packages/svelte-query/src/lib/createMutation.ts create mode 100644 packages/svelte-query/src/lib/createQueries.ts create mode 100644 packages/svelte-query/src/lib/createQuery.ts create mode 100644 packages/svelte-query/src/lib/index.ts create mode 100644 packages/svelte-query/src/lib/types.ts create mode 100644 packages/svelte-query/src/lib/useHydrate.ts create mode 100644 packages/svelte-query/src/lib/useIsFetching.ts create mode 100644 packages/svelte-query/src/lib/useIsMutating.ts create mode 100644 packages/svelte-query/src/lib/useQueryClient.ts create mode 100644 packages/svelte-query/static/emblem-light.svg create mode 100644 packages/svelte-query/svelte.config.js create mode 100644 packages/svelte-query/tsconfig.json create mode 100644 packages/svelte-query/vite.config.ts create mode 100644 packages/svelte-query/vitest.setup.ts diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json index c874df8427..e55f97ca72 100644 --- a/.codesandbox/ci.json +++ b/.codesandbox/ci.json @@ -1,6 +1,6 @@ { "installCommand": "install:csb", - "sandboxes": ["/examples/react/basic-typescript", "/examples/solid/basic-typescript", "/examples/vue/basic"], + "sandboxes": ["/examples/react/basic-typescript", "/examples/solid/basic-typescript", "/examples/svelte/basic", "/examples/vue/basic"], "packages": ["packages/**"], "node": "16" } diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..6da4f0816a --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +/packages/svelte-query/.svelte-kit diff --git a/babel.config.js b/babel.config.js index dc23100fd4..93f1b3251b 100644 --- a/babel.config.js +++ b/babel.config.js @@ -33,7 +33,7 @@ module.exports = { ].filter(Boolean), overrides: [ { - exclude: ['./packages/solid-query/**', './packages/vue-query/**'], + exclude: ['./packages/solid-query/**', './packages/svelte-query/**', './packages/vue-query/**'], presets: ['@babel/react'], }, { diff --git a/docs/config.json b/docs/config.json index 48282e3527..86118baba5 100644 --- a/docs/config.json +++ b/docs/config.json @@ -688,7 +688,7 @@ "label": "Getting Started", "children": [ { - "label": "Coming Soon", + "label": "Overview", "to": "svelte/overview" } ] diff --git a/docs/svelte/overview.md b/docs/svelte/overview.md index a7581f1c92..aeb846850d 100644 --- a/docs/svelte/overview.md +++ b/docs/svelte/overview.md @@ -1,8 +1,69 @@ --- id: overview -title: Svelte Query (Coming Soon) +title: Svelte Query --- -> ⚠️ This module has not yet been developed. It requires an adapter similar to `react-query` to work. We estimate the amount of code to do this is low-to-moderate, but does require familiarity with the Svelte framework. If you would like to contribute this adapter, please open a PR! +The `@tanstack/svelte-query` package offers a 1st-class API for using TanStack Query via Svelte. -The `@tanstack/svelte-query` package offers a 1st-class API for using TanStack Query via Svelte. However, all of the primitives you receive from this API are core APIs that are shared across all of the TanStack Adapters including the Query Client, query results, query subscriptions, etc. +## Example + +Include the QueryClientProvider near the root of your project: + +```svelte + + + + + +``` + +Then call any function (e.g. createQuery) from any component: + +```svelte + + +
+ {#if $query.isLoading} +

Loading...

+ {:else if $query.isError} +

Error: {$query.error.message}

+ {:else if $query.isSuccess} + {#each $query.data as todo} +

{todo.title}

+ {/each} + {/if} +
+``` + +## Available Functions + +Svelte Query offers useful functions and components that will make managing server state in Svelte apps easier. + +- `createQuery` +- `createQueries` +- `createInfiniteQuery` +- `createMutation` +- `useQueryClient` +- `useIsFetching` +- `useIsMutating` +- `useHydrate` +- `` +- `` + +## Important Differences between Svelte Query & React Query + +Svelte Query offers an API similar to React Query, but there are some key differences to be mindful of. + +- Many of the functions in Svelte Query return a Svelte store. To access values on these stores reactively, you need to prefix the store with a `$`. You can learn more about Svelte stores [here](https://svelte.dev/tutorial/writable-stores). diff --git a/examples/svelte/auto-refetching/.gitignore b/examples/svelte/auto-refetching/.gitignore new file mode 100644 index 0000000000..6fd24c7d48 --- /dev/null +++ b/examples/svelte/auto-refetching/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example +!lib/ diff --git a/examples/svelte/auto-refetching/README.md b/examples/svelte/auto-refetching/README.md new file mode 100644 index 0000000000..5c91169b0c --- /dev/null +++ b/examples/svelte/auto-refetching/README.md @@ -0,0 +1,38 @@ +# create-svelte + +Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```bash +# create a new project in the current directory +npm create svelte@latest + +# create a new project in my-app +npm create svelte@latest my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```bash +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. diff --git a/examples/svelte/auto-refetching/package.json b/examples/svelte/auto-refetching/package.json new file mode 100644 index 0000000000..d6432d57d7 --- /dev/null +++ b/examples/svelte/auto-refetching/package.json @@ -0,0 +1,25 @@ +{ + "name": "@tanstack/query-example-svelte-auto-refetching", + "version": "0.0.1", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json" + }, + "dependencies": { + "@tanstack/svelte-query": "^4.12.0" + }, + "devDependencies": { + "@sveltejs/adapter-auto": "^1.0.0", + "@sveltejs/kit": "^1.0.0", + "svelte": "^3.54.0", + "svelte-check": "^2.9.2", + "svelte-preprocess": "^4.10.7", + "tslib": "^2.4.1", + "typescript": "^4.7.4", + "vite": "^4.0.0" + }, + "type": "module" +} diff --git a/examples/svelte/auto-refetching/src/app.css b/examples/svelte/auto-refetching/src/app.css new file mode 100644 index 0000000000..c57658b1ef --- /dev/null +++ b/examples/svelte/auto-refetching/src/app.css @@ -0,0 +1,81 @@ +:root { + font-family: Inter, Avenir, Helvetica, Arial, sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +.card { + padding: 2em; +} + +main { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/examples/svelte/auto-refetching/src/app.d.ts b/examples/svelte/auto-refetching/src/app.d.ts new file mode 100644 index 0000000000..3e4ed2057b --- /dev/null +++ b/examples/svelte/auto-refetching/src/app.d.ts @@ -0,0 +1,9 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +// and what to do when importing types +declare namespace App { + // interface Locals {} + // interface PageData {} + // interface Error {} + // interface Platform {} +} diff --git a/examples/svelte/auto-refetching/src/app.html b/examples/svelte/auto-refetching/src/app.html new file mode 100644 index 0000000000..ab042806e7 --- /dev/null +++ b/examples/svelte/auto-refetching/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/examples/svelte/auto-refetching/src/routes/+layout.svelte b/examples/svelte/auto-refetching/src/routes/+layout.svelte new file mode 100644 index 0000000000..26fb7c0a93 --- /dev/null +++ b/examples/svelte/auto-refetching/src/routes/+layout.svelte @@ -0,0 +1,12 @@ + + + +
+ +
+
diff --git a/examples/svelte/auto-refetching/src/routes/+page.svelte b/examples/svelte/auto-refetching/src/routes/+page.svelte new file mode 100644 index 0000000000..62caf36a6f --- /dev/null +++ b/examples/svelte/auto-refetching/src/routes/+page.svelte @@ -0,0 +1,101 @@ + + +

Auto Refetch with stale-time set to 1s

+ +

+ This example is best experienced on your own machine, where you can open + multiple tabs to the same localhost server and see your changes propagate + between the two. +

+ + +

Todo List

+
{ + e.preventDefault() + e.stopPropagation() + $addMutation.mutate(value, { + onSuccess: () => (value = ''), + }) + }} +> + +
+ +{#if $todos.isLoading} + Loading... +{/if} +{#if $todos.error} + An error has occurred: + {$todos.error.message} +{/if} +{#if $todos.isSuccess} +
    + {#each $todos.data.items as item} +
  • {item}
  • + {/each} +
+
+ +
+{/if} +{#if $todos.isFetching} +
+ 'Background Updating...' : ' ' +
+{/if} + + diff --git a/examples/svelte/auto-refetching/src/routes/api/data/+server.ts b/examples/svelte/auto-refetching/src/routes/api/data/+server.ts new file mode 100644 index 0000000000..5b12a9d23c --- /dev/null +++ b/examples/svelte/auto-refetching/src/routes/api/data/+server.ts @@ -0,0 +1,19 @@ +import { json, type RequestHandler } from '@sveltejs/kit' + +let list = { items: ['Item 1', 'Item 2', 'Item 3'] } + +/** @type {import('./$types').RequestHandler} */ +export const GET: RequestHandler = async ({ url }) => { + const add = url.searchParams.get('add') + const clear = url.searchParams.get('clear') + + if (add) { + if (!list.items.includes(add)) { + list.items.push(add) + } + } else if (clear) { + list.items = [] + } + await new Promise((r) => setTimeout(r, 1000)) + return json(list, { status: 200 }) +} diff --git a/examples/svelte/auto-refetching/static/emblem-light.svg b/examples/svelte/auto-refetching/static/emblem-light.svg new file mode 100644 index 0000000000..a58e69ad5e --- /dev/null +++ b/examples/svelte/auto-refetching/static/emblem-light.svg @@ -0,0 +1,13 @@ + + + + emblem-light + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/examples/svelte/auto-refetching/svelte.config.js b/examples/svelte/auto-refetching/svelte.config.js new file mode 100644 index 0000000000..23f07d2032 --- /dev/null +++ b/examples/svelte/auto-refetching/svelte.config.js @@ -0,0 +1,15 @@ +import adapter from '@sveltejs/adapter-auto'; +import preprocess from 'svelte-preprocess'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://github.com/sveltejs/svelte-preprocess + // for more information about preprocessors + preprocess: preprocess(), + + kit: { + adapter: adapter() + } +}; + +export default config; diff --git a/examples/svelte/auto-refetching/tsconfig.json b/examples/svelte/auto-refetching/tsconfig.json new file mode 100644 index 0000000000..794b95b642 --- /dev/null +++ b/examples/svelte/auto-refetching/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true + } + // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/examples/svelte/auto-refetching/vite.config.ts b/examples/svelte/auto-refetching/vite.config.ts new file mode 100644 index 0000000000..f2eb6d93cf --- /dev/null +++ b/examples/svelte/auto-refetching/vite.config.ts @@ -0,0 +1,8 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import type { UserConfig } from 'vite'; + +const config: UserConfig = { + plugins: [sveltekit()] +}; + +export default config; diff --git a/examples/svelte/basic/.gitignore b/examples/svelte/basic/.gitignore new file mode 100644 index 0000000000..59362fd3fa --- /dev/null +++ b/examples/svelte/basic/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local +!lib/ + +# Editor directories and files +.vscode +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/examples/svelte/basic/README.md b/examples/svelte/basic/README.md new file mode 100644 index 0000000000..4ef762ffec --- /dev/null +++ b/examples/svelte/basic/README.md @@ -0,0 +1,48 @@ +# Svelte + TS + Vite + +This template should help get you started developing with Svelte and TypeScript in Vite. + +## Recommended IDE Setup + +[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). + +## Need an official Svelte framework? + +Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. + +## Technical considerations + +**Why use this over SvelteKit?** + +- It brings its own routing solution which might not be preferable for some users. +- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. + `vite dev` and `vite build` wouldn't work in a SvelteKit environment, for example. + +This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. + +Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. + +**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** + +Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. + +**Why include `.vscode/extensions.json`?** + +Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. + +**Why enable `allowJs` in the TS template?** + +While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. + +**Why is HMR not preserving my local component state?** + +HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). + +If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. + +```ts +// store.ts +// An extremely simple external store +import { writable } from 'svelte/store' +export default writable(0) +``` diff --git a/examples/svelte/basic/index.html b/examples/svelte/basic/index.html new file mode 100644 index 0000000000..8fe436406e --- /dev/null +++ b/examples/svelte/basic/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + Svelte + TS + + +
+ + + diff --git a/examples/svelte/basic/package.json b/examples/svelte/basic/package.json new file mode 100644 index 0000000000..b25206615b --- /dev/null +++ b/examples/svelte/basic/package.json @@ -0,0 +1,25 @@ +{ + "name": "@tanstack/query-example-svelte-basic", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-check --tsconfig ./tsconfig.json" + }, + "dependencies": { + "@tanstack/svelte-query": "^4.12.0" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^1.0.2", + "@tsconfig/svelte": "^3.0.0", + "svelte": "^3.54.0", + "svelte-check": "^2.9.2", + "svelte-preprocess": "^4.10.7", + "tslib": "^2.4.1", + "typescript": "^4.7.4", + "vite": "^3.1.0" + } +} diff --git a/examples/svelte/basic/public/emblem-light.svg b/examples/svelte/basic/public/emblem-light.svg new file mode 100644 index 0000000000..a58e69ad5e --- /dev/null +++ b/examples/svelte/basic/public/emblem-light.svg @@ -0,0 +1,13 @@ + + + + emblem-light + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/examples/svelte/basic/src/App.svelte b/examples/svelte/basic/src/App.svelte new file mode 100644 index 0000000000..33c1c6e297 --- /dev/null +++ b/examples/svelte/basic/src/App.svelte @@ -0,0 +1,13 @@ + + + +
+

Basic Query

+ +
+
diff --git a/examples/svelte/basic/src/app.css b/examples/svelte/basic/src/app.css new file mode 100644 index 0000000000..bcc7233dd1 --- /dev/null +++ b/examples/svelte/basic/src/app.css @@ -0,0 +1,81 @@ +:root { + font-family: Inter, Avenir, Helvetica, Arial, sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +.card { + padding: 2em; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/examples/svelte/basic/src/assets/svelte.svg b/examples/svelte/basic/src/assets/svelte.svg new file mode 100644 index 0000000000..c5e08481f8 --- /dev/null +++ b/examples/svelte/basic/src/assets/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/svelte/basic/src/lib/BasicQuery.svelte b/examples/svelte/basic/src/lib/BasicQuery.svelte new file mode 100644 index 0000000000..3f14271a5b --- /dev/null +++ b/examples/svelte/basic/src/lib/BasicQuery.svelte @@ -0,0 +1,15 @@ + + +{#if postId > -1} + +{:else} + +{/if} diff --git a/examples/svelte/basic/src/lib/Post.svelte b/examples/svelte/basic/src/lib/Post.svelte new file mode 100644 index 0000000000..1c13cf4be3 --- /dev/null +++ b/examples/svelte/basic/src/lib/Post.svelte @@ -0,0 +1,34 @@ + + +
+
+ +
+ {#if !postId || $post.isLoading} + Loading... + {/if} + {#if $post.error} + Error: {$post.error.message} + {/if} + {#if $post.isSuccess} +

{$post.data.title}

+
+

{$post.data.body}

+
+
{$post.isFetching ? 'Background Updating...' : ' '}
+ {/if} +
diff --git a/examples/svelte/basic/src/lib/Posts.svelte b/examples/svelte/basic/src/lib/Posts.svelte new file mode 100644 index 0000000000..0d3d63dad5 --- /dev/null +++ b/examples/svelte/basic/src/lib/Posts.svelte @@ -0,0 +1,61 @@ + + +
+
+ {#if $posts.status === 'loading'} + Loading... + {:else if $posts.status === 'error'} + Error: {$posts.error.message} + {:else} + + {#if $posts.isFetching} +
+ Background Updating... +
+ {/if} + {/if} +
+
+ + diff --git a/examples/svelte/basic/src/lib/data.ts b/examples/svelte/basic/src/lib/data.ts new file mode 100644 index 0000000000..d401b35752 --- /dev/null +++ b/examples/svelte/basic/src/lib/data.ts @@ -0,0 +1,16 @@ +export type Post = { id: number; title: string; body: string } + +export const limit = 10 + +export const getPosts = async (limit: number) => { + const parsed = await fetch('https://jsonplaceholder.typicode.com/posts').then( + (r) => r.json(), + ) + const result = parsed.filter((x: Post) => x.id <= limit) + return result +} + +export const getPostById = async (id: number) => + await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`).then((r) => + r.json(), + ) diff --git a/examples/svelte/basic/src/main.ts b/examples/svelte/basic/src/main.ts new file mode 100644 index 0000000000..8a909a15a0 --- /dev/null +++ b/examples/svelte/basic/src/main.ts @@ -0,0 +1,8 @@ +import './app.css' +import App from './App.svelte' + +const app = new App({ + target: document.getElementById('app'), +}) + +export default app diff --git a/examples/svelte/basic/src/vite-env.d.ts b/examples/svelte/basic/src/vite-env.d.ts new file mode 100644 index 0000000000..4078e7476a --- /dev/null +++ b/examples/svelte/basic/src/vite-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/examples/svelte/basic/svelte.config.js b/examples/svelte/basic/svelte.config.js new file mode 100644 index 0000000000..3630bb3963 --- /dev/null +++ b/examples/svelte/basic/svelte.config.js @@ -0,0 +1,7 @@ +import sveltePreprocess from 'svelte-preprocess' + +export default { + // Consult https://github.com/sveltejs/svelte-preprocess + // for more information about preprocessors + preprocess: sveltePreprocess() +} diff --git a/examples/svelte/basic/tsconfig.json b/examples/svelte/basic/tsconfig.json new file mode 100644 index 0000000000..d38303196a --- /dev/null +++ b/examples/svelte/basic/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "@tsconfig/svelte/tsconfig.json", + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "resolveJsonModule": true, + "baseUrl": ".", + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable checkJs if you'd like to use dynamic types in JS. + * Note that setting allowJs false does not prevent the use + * of JS in `.svelte` files. + */ + "allowJs": true, + "checkJs": true, + "isolatedModules": true + }, + "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/examples/svelte/basic/tsconfig.node.json b/examples/svelte/basic/tsconfig.node.json new file mode 100644 index 0000000000..65dbdb96ae --- /dev/null +++ b/examples/svelte/basic/tsconfig.node.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node" + }, + "include": ["vite.config.ts"] +} diff --git a/examples/svelte/basic/vite.config.ts b/examples/svelte/basic/vite.config.ts new file mode 100644 index 0000000000..401b4d4bd6 --- /dev/null +++ b/examples/svelte/basic/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import { svelte } from '@sveltejs/vite-plugin-svelte' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [svelte()] +}) diff --git a/examples/svelte/hydration/.gitignore b/examples/svelte/hydration/.gitignore new file mode 100644 index 0000000000..6fd24c7d48 --- /dev/null +++ b/examples/svelte/hydration/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example +!lib/ diff --git a/examples/svelte/hydration/README.md b/examples/svelte/hydration/README.md new file mode 100644 index 0000000000..5c91169b0c --- /dev/null +++ b/examples/svelte/hydration/README.md @@ -0,0 +1,38 @@ +# create-svelte + +Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```bash +# create a new project in the current directory +npm create svelte@latest + +# create a new project in my-app +npm create svelte@latest my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```bash +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. diff --git a/examples/svelte/hydration/package.json b/examples/svelte/hydration/package.json new file mode 100644 index 0000000000..4fd347a946 --- /dev/null +++ b/examples/svelte/hydration/package.json @@ -0,0 +1,25 @@ +{ + "name": "@tanstack/query-example-svelte-hydration", + "version": "0.0.1", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json" + }, + "dependencies": { + "@tanstack/svelte-query": "^4.12.0" + }, + "devDependencies": { + "@sveltejs/adapter-auto": "^1.0.0", + "@sveltejs/kit": "^1.0.0", + "svelte": "^3.54.0", + "svelte-check": "^2.9.2", + "svelte-preprocess": "^4.10.7", + "tslib": "^2.4.1", + "typescript": "^4.7.4", + "vite": "^4.0.0" + }, + "type": "module" +} diff --git a/examples/svelte/hydration/src/app.css b/examples/svelte/hydration/src/app.css new file mode 100644 index 0000000000..c57658b1ef --- /dev/null +++ b/examples/svelte/hydration/src/app.css @@ -0,0 +1,81 @@ +:root { + font-family: Inter, Avenir, Helvetica, Arial, sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +.card { + padding: 2em; +} + +main { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/examples/svelte/hydration/src/app.d.ts b/examples/svelte/hydration/src/app.d.ts new file mode 100644 index 0000000000..3e4ed2057b --- /dev/null +++ b/examples/svelte/hydration/src/app.d.ts @@ -0,0 +1,9 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +// and what to do when importing types +declare namespace App { + // interface Locals {} + // interface PageData {} + // interface Error {} + // interface Platform {} +} diff --git a/examples/svelte/hydration/src/app.html b/examples/svelte/hydration/src/app.html new file mode 100644 index 0000000000..bf205c1085 --- /dev/null +++ b/examples/svelte/hydration/src/app.html @@ -0,0 +1,11 @@ + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/examples/svelte/hydration/src/lib/Post.svelte b/examples/svelte/hydration/src/lib/Post.svelte new file mode 100644 index 0000000000..1c13cf4be3 --- /dev/null +++ b/examples/svelte/hydration/src/lib/Post.svelte @@ -0,0 +1,34 @@ + + +
+
+ +
+ {#if !postId || $post.isLoading} + Loading... + {/if} + {#if $post.error} + Error: {$post.error.message} + {/if} + {#if $post.isSuccess} +

{$post.data.title}

+
+

{$post.data.body}

+
+
{$post.isFetching ? 'Background Updating...' : ' '}
+ {/if} +
diff --git a/examples/svelte/hydration/src/lib/Posts.svelte b/examples/svelte/hydration/src/lib/Posts.svelte new file mode 100644 index 0000000000..0d3d63dad5 --- /dev/null +++ b/examples/svelte/hydration/src/lib/Posts.svelte @@ -0,0 +1,61 @@ + + +
+
+ {#if $posts.status === 'loading'} + Loading... + {:else if $posts.status === 'error'} + Error: {$posts.error.message} + {:else} + + {#if $posts.isFetching} +
+ Background Updating... +
+ {/if} + {/if} +
+
+ + diff --git a/examples/svelte/hydration/src/lib/data.ts b/examples/svelte/hydration/src/lib/data.ts new file mode 100644 index 0000000000..d401b35752 --- /dev/null +++ b/examples/svelte/hydration/src/lib/data.ts @@ -0,0 +1,16 @@ +export type Post = { id: number; title: string; body: string } + +export const limit = 10 + +export const getPosts = async (limit: number) => { + const parsed = await fetch('https://jsonplaceholder.typicode.com/posts').then( + (r) => r.json(), + ) + const result = parsed.filter((x: Post) => x.id <= limit) + return result +} + +export const getPostById = async (id: number) => + await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`).then((r) => + r.json(), + ) diff --git a/examples/svelte/hydration/src/lib/store.ts b/examples/svelte/hydration/src/lib/store.ts new file mode 100644 index 0000000000..79ab749fdf --- /dev/null +++ b/examples/svelte/hydration/src/lib/store.ts @@ -0,0 +1,4 @@ +import type { DehydratedState } from '@tanstack/query-core' +import { writable } from 'svelte/store' + +export const dehydratedState = writable() diff --git a/examples/svelte/hydration/src/routes/+layout.svelte b/examples/svelte/hydration/src/routes/+layout.svelte new file mode 100644 index 0000000000..97f28d6ee6 --- /dev/null +++ b/examples/svelte/hydration/src/routes/+layout.svelte @@ -0,0 +1,19 @@ + + + + +
+ +
+
+
diff --git a/examples/svelte/hydration/src/routes/+page.svelte b/examples/svelte/hydration/src/routes/+page.svelte new file mode 100644 index 0000000000..26ce099089 --- /dev/null +++ b/examples/svelte/hydration/src/routes/+page.svelte @@ -0,0 +1,31 @@ + + +

Basic Query with Hydration

+{#if postId > -1} + +{:else} + +{/if} + + diff --git a/examples/svelte/hydration/src/routes/+page.ts b/examples/svelte/hydration/src/routes/+page.ts new file mode 100644 index 0000000000..e1a3833970 --- /dev/null +++ b/examples/svelte/hydration/src/routes/+page.ts @@ -0,0 +1,16 @@ +import { dehydrate, QueryClient } from '@tanstack/svelte-query' +import { getPosts, limit } from '$lib/data.js' +import type { PageLoad } from './$types' + +export const load: PageLoad = async () => { + const queryClient = new QueryClient() + + await queryClient.prefetchQuery({ + queryKey: ['posts', limit], + queryFn: () => getPosts(limit), + }) + + return { + dehydratedState: dehydrate(queryClient), + } +} diff --git a/examples/svelte/hydration/src/routes/api/data/+server.ts b/examples/svelte/hydration/src/routes/api/data/+server.ts new file mode 100644 index 0000000000..301018f5cc --- /dev/null +++ b/examples/svelte/hydration/src/routes/api/data/+server.ts @@ -0,0 +1,29 @@ +import { json, type RequestHandler } from '@sveltejs/kit' + +type Todo = { + id: string + text: string +} + +const items: Todo[] = [] + +/** @type {import('./$types').RequestHandler} */ +export const GET: RequestHandler = async (req) => { + await new Promise((r) => setTimeout(r, 1000)) + return json({ ts: Date.now(), items }, { status: 200 }) +} + +/** @type {import('./$types').RequestHandler} */ +export const POST: RequestHandler = async ({ request }) => { + const { text } = await request.json() + + if (Math.random() > 0.7) { + json({ message: 'Could not add item!' }, { status: 500 }) + } + const newTodo = { + id: Math.random().toString(), + text: text.toUpperCase() as string, + } + items.push(newTodo) + return json(newTodo, { status: 200 }) +} diff --git a/examples/svelte/hydration/static/emblem-light.svg b/examples/svelte/hydration/static/emblem-light.svg new file mode 100644 index 0000000000..a58e69ad5e --- /dev/null +++ b/examples/svelte/hydration/static/emblem-light.svg @@ -0,0 +1,13 @@ + + + + emblem-light + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/examples/svelte/hydration/svelte.config.js b/examples/svelte/hydration/svelte.config.js new file mode 100644 index 0000000000..23f07d2032 --- /dev/null +++ b/examples/svelte/hydration/svelte.config.js @@ -0,0 +1,15 @@ +import adapter from '@sveltejs/adapter-auto'; +import preprocess from 'svelte-preprocess'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://github.com/sveltejs/svelte-preprocess + // for more information about preprocessors + preprocess: preprocess(), + + kit: { + adapter: adapter() + } +}; + +export default config; diff --git a/examples/svelte/hydration/tsconfig.json b/examples/svelte/hydration/tsconfig.json new file mode 100644 index 0000000000..794b95b642 --- /dev/null +++ b/examples/svelte/hydration/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true + } + // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/examples/svelte/hydration/vite.config.ts b/examples/svelte/hydration/vite.config.ts new file mode 100644 index 0000000000..f2eb6d93cf --- /dev/null +++ b/examples/svelte/hydration/vite.config.ts @@ -0,0 +1,8 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import type { UserConfig } from 'vite'; + +const config: UserConfig = { + plugins: [sveltekit()] +}; + +export default config; diff --git a/examples/svelte/infinite-loadmore/.gitignore b/examples/svelte/infinite-loadmore/.gitignore new file mode 100644 index 0000000000..59362fd3fa --- /dev/null +++ b/examples/svelte/infinite-loadmore/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local +!lib/ + +# Editor directories and files +.vscode +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/examples/svelte/infinite-loadmore/README.md b/examples/svelte/infinite-loadmore/README.md new file mode 100644 index 0000000000..4ef762ffec --- /dev/null +++ b/examples/svelte/infinite-loadmore/README.md @@ -0,0 +1,48 @@ +# Svelte + TS + Vite + +This template should help get you started developing with Svelte and TypeScript in Vite. + +## Recommended IDE Setup + +[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). + +## Need an official Svelte framework? + +Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. + +## Technical considerations + +**Why use this over SvelteKit?** + +- It brings its own routing solution which might not be preferable for some users. +- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. + `vite dev` and `vite build` wouldn't work in a SvelteKit environment, for example. + +This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. + +Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. + +**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** + +Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. + +**Why include `.vscode/extensions.json`?** + +Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. + +**Why enable `allowJs` in the TS template?** + +While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. + +**Why is HMR not preserving my local component state?** + +HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). + +If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. + +```ts +// store.ts +// An extremely simple external store +import { writable } from 'svelte/store' +export default writable(0) +``` diff --git a/examples/svelte/infinite-loadmore/index.html b/examples/svelte/infinite-loadmore/index.html new file mode 100644 index 0000000000..8fe436406e --- /dev/null +++ b/examples/svelte/infinite-loadmore/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + Svelte + TS + + +
+ + + diff --git a/examples/svelte/infinite-loadmore/package.json b/examples/svelte/infinite-loadmore/package.json new file mode 100644 index 0000000000..3c05d84c76 --- /dev/null +++ b/examples/svelte/infinite-loadmore/package.json @@ -0,0 +1,25 @@ +{ + "name": "@tanstack/query-example-svelte-infinite-loadmore", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-check --tsconfig ./tsconfig.json" + }, + "dependencies": { + "@tanstack/svelte-query": "^4.12.0" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^1.0.2", + "@tsconfig/svelte": "^3.0.0", + "svelte": "^3.54.0", + "svelte-check": "^2.9.2", + "svelte-preprocess": "^4.10.7", + "tslib": "^2.4.1", + "typescript": "^4.7.4", + "vite": "^3.1.0" + } +} diff --git a/examples/svelte/infinite-loadmore/public/emblem-light.svg b/examples/svelte/infinite-loadmore/public/emblem-light.svg new file mode 100644 index 0000000000..a58e69ad5e --- /dev/null +++ b/examples/svelte/infinite-loadmore/public/emblem-light.svg @@ -0,0 +1,13 @@ + + + + emblem-light + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/examples/svelte/infinite-loadmore/src/App.svelte b/examples/svelte/infinite-loadmore/src/App.svelte new file mode 100644 index 0000000000..1c3b2c1007 --- /dev/null +++ b/examples/svelte/infinite-loadmore/src/App.svelte @@ -0,0 +1,13 @@ + + + +
+

Infinte Load More

+ +
+
diff --git a/examples/svelte/infinite-loadmore/src/app.css b/examples/svelte/infinite-loadmore/src/app.css new file mode 100644 index 0000000000..bcc7233dd1 --- /dev/null +++ b/examples/svelte/infinite-loadmore/src/app.css @@ -0,0 +1,81 @@ +:root { + font-family: Inter, Avenir, Helvetica, Arial, sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +.card { + padding: 2em; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/examples/svelte/infinite-loadmore/src/assets/svelte.svg b/examples/svelte/infinite-loadmore/src/assets/svelte.svg new file mode 100644 index 0000000000..c5e08481f8 --- /dev/null +++ b/examples/svelte/infinite-loadmore/src/assets/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/svelte/infinite-loadmore/src/lib/LoadMore.svelte b/examples/svelte/infinite-loadmore/src/lib/LoadMore.svelte new file mode 100644 index 0000000000..743d8da7cc --- /dev/null +++ b/examples/svelte/infinite-loadmore/src/lib/LoadMore.svelte @@ -0,0 +1,66 @@ + + +{#if $query.isLoading} + Loading... +{/if} +{#if $query.error} + Error: {error.message} +{/if} +{#if $query.isSuccess} +
+ {#each $query.data.pages as { results }} + {#each results as planet} +
+
+

Planet Name: {planet.name}

+

Population: {planet.population}

+
+
+ {/each} + {/each} +
+
+ +
+{/if} + + diff --git a/examples/svelte/infinite-loadmore/src/main.ts b/examples/svelte/infinite-loadmore/src/main.ts new file mode 100644 index 0000000000..8a909a15a0 --- /dev/null +++ b/examples/svelte/infinite-loadmore/src/main.ts @@ -0,0 +1,8 @@ +import './app.css' +import App from './App.svelte' + +const app = new App({ + target: document.getElementById('app'), +}) + +export default app diff --git a/examples/svelte/infinite-loadmore/src/vite-env.d.ts b/examples/svelte/infinite-loadmore/src/vite-env.d.ts new file mode 100644 index 0000000000..4078e7476a --- /dev/null +++ b/examples/svelte/infinite-loadmore/src/vite-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/examples/svelte/infinite-loadmore/svelte.config.js b/examples/svelte/infinite-loadmore/svelte.config.js new file mode 100644 index 0000000000..3630bb3963 --- /dev/null +++ b/examples/svelte/infinite-loadmore/svelte.config.js @@ -0,0 +1,7 @@ +import sveltePreprocess from 'svelte-preprocess' + +export default { + // Consult https://github.com/sveltejs/svelte-preprocess + // for more information about preprocessors + preprocess: sveltePreprocess() +} diff --git a/examples/svelte/infinite-loadmore/tsconfig.json b/examples/svelte/infinite-loadmore/tsconfig.json new file mode 100644 index 0000000000..d38303196a --- /dev/null +++ b/examples/svelte/infinite-loadmore/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "@tsconfig/svelte/tsconfig.json", + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "resolveJsonModule": true, + "baseUrl": ".", + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable checkJs if you'd like to use dynamic types in JS. + * Note that setting allowJs false does not prevent the use + * of JS in `.svelte` files. + */ + "allowJs": true, + "checkJs": true, + "isolatedModules": true + }, + "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/examples/svelte/infinite-loadmore/tsconfig.node.json b/examples/svelte/infinite-loadmore/tsconfig.node.json new file mode 100644 index 0000000000..65dbdb96ae --- /dev/null +++ b/examples/svelte/infinite-loadmore/tsconfig.node.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node" + }, + "include": ["vite.config.ts"] +} diff --git a/examples/svelte/infinite-loadmore/vite.config.ts b/examples/svelte/infinite-loadmore/vite.config.ts new file mode 100644 index 0000000000..401b4d4bd6 --- /dev/null +++ b/examples/svelte/infinite-loadmore/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import { svelte } from '@sveltejs/vite-plugin-svelte' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [svelte()] +}) diff --git a/examples/svelte/optimistic-updates-typescript/.gitignore b/examples/svelte/optimistic-updates-typescript/.gitignore new file mode 100644 index 0000000000..6fd24c7d48 --- /dev/null +++ b/examples/svelte/optimistic-updates-typescript/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example +!lib/ diff --git a/examples/svelte/optimistic-updates-typescript/README.md b/examples/svelte/optimistic-updates-typescript/README.md new file mode 100644 index 0000000000..5c91169b0c --- /dev/null +++ b/examples/svelte/optimistic-updates-typescript/README.md @@ -0,0 +1,38 @@ +# create-svelte + +Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```bash +# create a new project in the current directory +npm create svelte@latest + +# create a new project in my-app +npm create svelte@latest my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```bash +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. diff --git a/examples/svelte/optimistic-updates-typescript/package.json b/examples/svelte/optimistic-updates-typescript/package.json new file mode 100644 index 0000000000..ecb0a68baf --- /dev/null +++ b/examples/svelte/optimistic-updates-typescript/package.json @@ -0,0 +1,25 @@ +{ + "name": "@tanstack/query-example-svelte-optimistic-updates-typescript", + "version": "0.0.1", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json" + }, + "dependencies": { + "@tanstack/svelte-query": "^4.12.0" + }, + "devDependencies": { + "@sveltejs/adapter-auto": "^1.0.0", + "@sveltejs/kit": "^1.0.0", + "svelte": "^3.54.0", + "svelte-check": "^2.9.2", + "svelte-preprocess": "^4.10.7", + "tslib": "^2.4.1", + "typescript": "^4.7.4", + "vite": "^4.0.0" + }, + "type": "module" +} diff --git a/examples/svelte/optimistic-updates-typescript/src/app.css b/examples/svelte/optimistic-updates-typescript/src/app.css new file mode 100644 index 0000000000..c57658b1ef --- /dev/null +++ b/examples/svelte/optimistic-updates-typescript/src/app.css @@ -0,0 +1,81 @@ +:root { + font-family: Inter, Avenir, Helvetica, Arial, sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +.card { + padding: 2em; +} + +main { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/examples/svelte/optimistic-updates-typescript/src/app.d.ts b/examples/svelte/optimistic-updates-typescript/src/app.d.ts new file mode 100644 index 0000000000..3e4ed2057b --- /dev/null +++ b/examples/svelte/optimistic-updates-typescript/src/app.d.ts @@ -0,0 +1,9 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +// and what to do when importing types +declare namespace App { + // interface Locals {} + // interface PageData {} + // interface Error {} + // interface Platform {} +} diff --git a/examples/svelte/optimistic-updates-typescript/src/app.html b/examples/svelte/optimistic-updates-typescript/src/app.html new file mode 100644 index 0000000000..ab042806e7 --- /dev/null +++ b/examples/svelte/optimistic-updates-typescript/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/examples/svelte/optimistic-updates-typescript/src/routes/+layout.svelte b/examples/svelte/optimistic-updates-typescript/src/routes/+layout.svelte new file mode 100644 index 0000000000..26fb7c0a93 --- /dev/null +++ b/examples/svelte/optimistic-updates-typescript/src/routes/+layout.svelte @@ -0,0 +1,12 @@ + + + +
+ +
+
diff --git a/examples/svelte/optimistic-updates-typescript/src/routes/+page.svelte b/examples/svelte/optimistic-updates-typescript/src/routes/+page.svelte new file mode 100644 index 0000000000..cfc926a4e5 --- /dev/null +++ b/examples/svelte/optimistic-updates-typescript/src/routes/+page.svelte @@ -0,0 +1,129 @@ + + +

Optimistic Updates

+

+ In this example, new items can be created using a mutation. The new item will + be optimistically added to the list in hopes that the server accepts the item. + If it does, the list is refetched with the true items from the list. Every now + and then, the mutation may fail though. When that happens, the previous list + of items is restored and the list is again refetched from the server. +

+ +
{ + e.preventDefault() + e.stopPropagation() + $addTodoMutation.mutate(text) + }} +> +
+ + +
+
+ +{#if $todos.isLoading} + Loading... +{/if} +{#if $todos.error} + An error has occurred: + {$todos.error.message} +{/if} +{#if $todos.isSuccess} +
+ Updated At: {new Date($todos.data.ts).toLocaleTimeString()} +
+
    + {#each $todos.data.items as todo} +
  • {todo.text}
  • + {/each} +
+{/if} +{#if $todos.isFetching} +
+ 'Background Updating...' : ' ' +
+{/if} + + diff --git a/examples/svelte/optimistic-updates-typescript/src/routes/api/data/+server.ts b/examples/svelte/optimistic-updates-typescript/src/routes/api/data/+server.ts new file mode 100644 index 0000000000..301018f5cc --- /dev/null +++ b/examples/svelte/optimistic-updates-typescript/src/routes/api/data/+server.ts @@ -0,0 +1,29 @@ +import { json, type RequestHandler } from '@sveltejs/kit' + +type Todo = { + id: string + text: string +} + +const items: Todo[] = [] + +/** @type {import('./$types').RequestHandler} */ +export const GET: RequestHandler = async (req) => { + await new Promise((r) => setTimeout(r, 1000)) + return json({ ts: Date.now(), items }, { status: 200 }) +} + +/** @type {import('./$types').RequestHandler} */ +export const POST: RequestHandler = async ({ request }) => { + const { text } = await request.json() + + if (Math.random() > 0.7) { + json({ message: 'Could not add item!' }, { status: 500 }) + } + const newTodo = { + id: Math.random().toString(), + text: text.toUpperCase() as string, + } + items.push(newTodo) + return json(newTodo, { status: 200 }) +} diff --git a/examples/svelte/optimistic-updates-typescript/static/emblem-light.svg b/examples/svelte/optimistic-updates-typescript/static/emblem-light.svg new file mode 100644 index 0000000000..a58e69ad5e --- /dev/null +++ b/examples/svelte/optimistic-updates-typescript/static/emblem-light.svg @@ -0,0 +1,13 @@ + + + + emblem-light + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/examples/svelte/optimistic-updates-typescript/svelte.config.js b/examples/svelte/optimistic-updates-typescript/svelte.config.js new file mode 100644 index 0000000000..23f07d2032 --- /dev/null +++ b/examples/svelte/optimistic-updates-typescript/svelte.config.js @@ -0,0 +1,15 @@ +import adapter from '@sveltejs/adapter-auto'; +import preprocess from 'svelte-preprocess'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://github.com/sveltejs/svelte-preprocess + // for more information about preprocessors + preprocess: preprocess(), + + kit: { + adapter: adapter() + } +}; + +export default config; diff --git a/examples/svelte/optimistic-updates-typescript/tsconfig.json b/examples/svelte/optimistic-updates-typescript/tsconfig.json new file mode 100644 index 0000000000..794b95b642 --- /dev/null +++ b/examples/svelte/optimistic-updates-typescript/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true + } + // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/examples/svelte/optimistic-updates-typescript/vite.config.ts b/examples/svelte/optimistic-updates-typescript/vite.config.ts new file mode 100644 index 0000000000..f2eb6d93cf --- /dev/null +++ b/examples/svelte/optimistic-updates-typescript/vite.config.ts @@ -0,0 +1,8 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import type { UserConfig } from 'vite'; + +const config: UserConfig = { + plugins: [sveltekit()] +}; + +export default config; diff --git a/examples/svelte/playground/.gitignore b/examples/svelte/playground/.gitignore new file mode 100644 index 0000000000..6fd24c7d48 --- /dev/null +++ b/examples/svelte/playground/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example +!lib/ diff --git a/examples/svelte/playground/README.md b/examples/svelte/playground/README.md new file mode 100644 index 0000000000..678586e2c5 --- /dev/null +++ b/examples/svelte/playground/README.md @@ -0,0 +1,8 @@ +# Example + +This example is a rewrite of the React Query playground example. + +To run this example: + +- `npm install` +- `npm run dev` diff --git a/examples/svelte/playground/package.json b/examples/svelte/playground/package.json new file mode 100644 index 0000000000..125de2873b --- /dev/null +++ b/examples/svelte/playground/package.json @@ -0,0 +1,24 @@ +{ + "name": "@tanstack/query-example-svelte-playground", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json" + }, + "dependencies": { + "@tanstack/svelte-query": "^4.12.0" + }, + "devDependencies": { + "@sveltejs/adapter-auto": "^1.0.0", + "@sveltejs/kit": "^1.0.0", + "svelte": "^3.54.0", + "svelte-check": "^2.9.2", + "tslib": "^2.4.1", + "typescript": "^4.7.4", + "vite": "^4.0.0" + } +} diff --git a/examples/svelte/playground/src/app.css b/examples/svelte/playground/src/app.css new file mode 100644 index 0000000000..eb5c0a46ab --- /dev/null +++ b/examples/svelte/playground/src/app.css @@ -0,0 +1,11 @@ +body { + margin: 0; + padding: 1rem; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", + "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + color: white; + background: #0b1521; +} diff --git a/examples/svelte/playground/src/app.d.ts b/examples/svelte/playground/src/app.d.ts new file mode 100644 index 0000000000..1cea0dcf2b --- /dev/null +++ b/examples/svelte/playground/src/app.d.ts @@ -0,0 +1,9 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +// and what to do when importing types +declare namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface Platform {} +} diff --git a/examples/svelte/playground/src/app.html b/examples/svelte/playground/src/app.html new file mode 100644 index 0000000000..d847151a12 --- /dev/null +++ b/examples/svelte/playground/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/examples/svelte/playground/src/lib/stores.ts b/examples/svelte/playground/src/lib/stores.ts new file mode 100644 index 0000000000..be3774f8bb --- /dev/null +++ b/examples/svelte/playground/src/lib/stores.ts @@ -0,0 +1,23 @@ +import { writable } from 'svelte/store' + +export const staleTime = writable(1000) +export const cacheTime = writable(3000) +export const errorRate = writable(0.05) +export const queryTimeMin = writable(1000) +export const queryTimeMax = writable(2000) + +export const editingIndex = writable(null) +export const views = writable(['', 'fruit', 'grape']) + +let initialId = 0 +const initialList = [ + 'apple', + 'banana', + 'pineapple', + 'grapefruit', + 'dragonfruit', + 'grapes', +].map((d) => ({ id: initialId++, name: d, notes: 'These are some notes' })) + +export const list = writable(initialList) +export const id = writable(initialId) diff --git a/examples/svelte/playground/src/routes/+layout.svelte b/examples/svelte/playground/src/routes/+layout.svelte new file mode 100644 index 0000000000..fffc9a57be --- /dev/null +++ b/examples/svelte/playground/src/routes/+layout.svelte @@ -0,0 +1,16 @@ + + + + Svelte Query Playground Example + + + +
+ +
+
diff --git a/examples/svelte/playground/src/routes/+page.svelte b/examples/svelte/playground/src/routes/+page.svelte new file mode 100644 index 0000000000..e222011bb2 --- /dev/null +++ b/examples/svelte/playground/src/routes/+page.svelte @@ -0,0 +1,81 @@ + + +

+ The "staleTime" and "cacheTime" durations have been altered in this example to + show how query stale-ness and query caching work on a granular level +

+
+ Stale Time:{' '} + +
+
+ Cache Time:{' '} + +
+
+
+ Error Rate:{' '} + +
+
+ Fetch Time Min:{' '} + {' '} +
+
+ Fetch Time Max:{' '} + +
+ +
+ +
diff --git a/examples/svelte/playground/src/routes/AddTodo.svelte b/examples/svelte/playground/src/routes/AddTodo.svelte new file mode 100644 index 0000000000..c92fc2e47f --- /dev/null +++ b/examples/svelte/playground/src/routes/AddTodo.svelte @@ -0,0 +1,57 @@ + + +
+ + + + +
+ {$addMutation.status === 'loading' + ? 'Saving...' + : $addMutation.status === 'error' + ? $addMutation.error.message + : 'Saved!'} +
+
diff --git a/examples/svelte/playground/src/routes/App.svelte b/examples/svelte/playground/src/routes/App.svelte new file mode 100644 index 0000000000..98fb2ad97d --- /dev/null +++ b/examples/svelte/playground/src/routes/App.svelte @@ -0,0 +1,42 @@ + + +
+
+ +
+
+
+ + {#each $views as view} +
+ +
+
+ {/each} + + +
+ + {#if $editingIndex !== null} + +
+ {/if} + + +
diff --git a/examples/svelte/playground/src/routes/EditTodo.svelte b/examples/svelte/playground/src/routes/EditTodo.svelte new file mode 100644 index 0000000000..fdf249a334 --- /dev/null +++ b/examples/svelte/playground/src/routes/EditTodo.svelte @@ -0,0 +1,118 @@ + + +
+
+ {#if $query.data} + Editing Todo + "{$query.data.name}" (#{$editingIndex}) + {/if} +
+ {#if $query.status === 'loading'} + Loading... (Attempt: {$query.failureCount + 1}) + {:else if $query.error} + + Error! + + {:else} + + +
+ +
+
+ {$saveMutation.status === 'loading' + ? 'Saving...' + : $saveMutation.status === 'error' + ? $saveMutation.error.message + : 'Saved!'} +
+
+ {#if $query.isFetching} + + Background Refreshing... (Attempt: {$query.failureCount + 1}) + + {:else} +   + {/if} +
+ {/if} +
diff --git a/examples/svelte/playground/src/routes/Todos.svelte b/examples/svelte/playground/src/routes/Todos.svelte new file mode 100644 index 0000000000..47b0b4387d --- /dev/null +++ b/examples/svelte/playground/src/routes/Todos.svelte @@ -0,0 +1,71 @@ + + +
+ +
+ +{#if $query.status === 'loading'} + Loading... (Attempt: {$query.failureCount + 1}) +{:else if $query.status === 'error'} + + Error: {$query.error.message} +
+ +
+{:else} +
    + {#if $query.data} + {#each $query.data as todo} +
  • + {todo.name}{' '} + +
  • + {/each} + {/if} +
+
+ {#if $query.isFetching} + + Background Refreshing... (Attempt: {$query.failureCount + 1}) + + {:else} +   + {/if} +
+{/if} diff --git a/examples/svelte/playground/static/emblem-light.svg b/examples/svelte/playground/static/emblem-light.svg new file mode 100644 index 0000000000..a58e69ad5e --- /dev/null +++ b/examples/svelte/playground/static/emblem-light.svg @@ -0,0 +1,13 @@ + + + + emblem-light + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/examples/svelte/playground/svelte.config.js b/examples/svelte/playground/svelte.config.js new file mode 100644 index 0000000000..a16d0de80a --- /dev/null +++ b/examples/svelte/playground/svelte.config.js @@ -0,0 +1,13 @@ +import adapter from '@sveltejs/adapter-auto'; +import { vitePreprocess } from '@sveltejs/kit/vite'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + preprocess: vitePreprocess(), + + kit: { + adapter: adapter() + } +}; + +export default config; diff --git a/examples/svelte/playground/tsconfig.json b/examples/svelte/playground/tsconfig.json new file mode 100644 index 0000000000..5c56cee332 --- /dev/null +++ b/examples/svelte/playground/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true + } +} diff --git a/examples/svelte/playground/vite.config.ts b/examples/svelte/playground/vite.config.ts new file mode 100644 index 0000000000..096c2069b7 --- /dev/null +++ b/examples/svelte/playground/vite.config.ts @@ -0,0 +1,8 @@ +import { sveltekit } from '@sveltejs/kit/vite'; + +/** @type {import('vite').UserConfig} */ +const config = { + plugins: [sveltekit()] +}; + +export default config; diff --git a/examples/svelte/simple/.gitignore b/examples/svelte/simple/.gitignore new file mode 100644 index 0000000000..59362fd3fa --- /dev/null +++ b/examples/svelte/simple/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local +!lib/ + +# Editor directories and files +.vscode +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/examples/svelte/simple/README.md b/examples/svelte/simple/README.md new file mode 100644 index 0000000000..4ef762ffec --- /dev/null +++ b/examples/svelte/simple/README.md @@ -0,0 +1,48 @@ +# Svelte + TS + Vite + +This template should help get you started developing with Svelte and TypeScript in Vite. + +## Recommended IDE Setup + +[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). + +## Need an official Svelte framework? + +Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. + +## Technical considerations + +**Why use this over SvelteKit?** + +- It brings its own routing solution which might not be preferable for some users. +- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. + `vite dev` and `vite build` wouldn't work in a SvelteKit environment, for example. + +This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. + +Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. + +**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** + +Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. + +**Why include `.vscode/extensions.json`?** + +Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. + +**Why enable `allowJs` in the TS template?** + +While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. + +**Why is HMR not preserving my local component state?** + +HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). + +If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. + +```ts +// store.ts +// An extremely simple external store +import { writable } from 'svelte/store' +export default writable(0) +``` diff --git a/examples/svelte/simple/index.html b/examples/svelte/simple/index.html new file mode 100644 index 0000000000..8fe436406e --- /dev/null +++ b/examples/svelte/simple/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + Svelte + TS + + +
+ + + diff --git a/examples/svelte/simple/package.json b/examples/svelte/simple/package.json new file mode 100644 index 0000000000..a9443f784e --- /dev/null +++ b/examples/svelte/simple/package.json @@ -0,0 +1,25 @@ +{ + "name": "@tanstack/query-example-svelte-simple", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-check --tsconfig ./tsconfig.json" + }, + "dependencies": { + "@tanstack/svelte-query": "^4.12.0" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^1.0.2", + "@tsconfig/svelte": "^3.0.0", + "svelte": "^3.54.0", + "svelte-check": "^2.9.2", + "svelte-preprocess": "^4.10.7", + "tslib": "^2.4.1", + "typescript": "^4.7.4", + "vite": "^3.1.0" + } +} diff --git a/examples/svelte/simple/public/emblem-light.svg b/examples/svelte/simple/public/emblem-light.svg new file mode 100644 index 0000000000..a58e69ad5e --- /dev/null +++ b/examples/svelte/simple/public/emblem-light.svg @@ -0,0 +1,13 @@ + + + + emblem-light + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/examples/svelte/simple/src/App.svelte b/examples/svelte/simple/src/App.svelte new file mode 100644 index 0000000000..76097f7e67 --- /dev/null +++ b/examples/svelte/simple/src/App.svelte @@ -0,0 +1,12 @@ + + + +
+ +
+
diff --git a/examples/svelte/simple/src/app.css b/examples/svelte/simple/src/app.css new file mode 100644 index 0000000000..bcc7233dd1 --- /dev/null +++ b/examples/svelte/simple/src/app.css @@ -0,0 +1,81 @@ +:root { + font-family: Inter, Avenir, Helvetica, Arial, sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +.card { + padding: 2em; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/examples/svelte/simple/src/assets/svelte.svg b/examples/svelte/simple/src/assets/svelte.svg new file mode 100644 index 0000000000..c5e08481f8 --- /dev/null +++ b/examples/svelte/simple/src/assets/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/svelte/simple/src/lib/Simple.svelte b/examples/svelte/simple/src/lib/Simple.svelte new file mode 100644 index 0000000000..a123d1e696 --- /dev/null +++ b/examples/svelte/simple/src/lib/Simple.svelte @@ -0,0 +1,41 @@ + + +

Simple

+
+
+ {#if $query.isLoading} + Loading... + {/if} + {#if $query.error} + An error has occurred: + {$query.error.message} + {/if} + {#if $query.isSuccess} +
+

{$query.data.name}

+

{$query.data.description}

+ 👀 {$query.data.subscribers_count}{' '} + ✨ {$query.data.stargazers_count}{' '} + 🍴 {$query.data.forks_count} +
+ {/if} +
+
diff --git a/examples/svelte/simple/src/main.ts b/examples/svelte/simple/src/main.ts new file mode 100644 index 0000000000..8a909a15a0 --- /dev/null +++ b/examples/svelte/simple/src/main.ts @@ -0,0 +1,8 @@ +import './app.css' +import App from './App.svelte' + +const app = new App({ + target: document.getElementById('app'), +}) + +export default app diff --git a/examples/svelte/simple/src/vite-env.d.ts b/examples/svelte/simple/src/vite-env.d.ts new file mode 100644 index 0000000000..4078e7476a --- /dev/null +++ b/examples/svelte/simple/src/vite-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/examples/svelte/simple/svelte.config.js b/examples/svelte/simple/svelte.config.js new file mode 100644 index 0000000000..3630bb3963 --- /dev/null +++ b/examples/svelte/simple/svelte.config.js @@ -0,0 +1,7 @@ +import sveltePreprocess from 'svelte-preprocess' + +export default { + // Consult https://github.com/sveltejs/svelte-preprocess + // for more information about preprocessors + preprocess: sveltePreprocess() +} diff --git a/examples/svelte/simple/tsconfig.json b/examples/svelte/simple/tsconfig.json new file mode 100644 index 0000000000..d38303196a --- /dev/null +++ b/examples/svelte/simple/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "@tsconfig/svelte/tsconfig.json", + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "resolveJsonModule": true, + "baseUrl": ".", + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable checkJs if you'd like to use dynamic types in JS. + * Note that setting allowJs false does not prevent the use + * of JS in `.svelte` files. + */ + "allowJs": true, + "checkJs": true, + "isolatedModules": true + }, + "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/examples/svelte/simple/tsconfig.node.json b/examples/svelte/simple/tsconfig.node.json new file mode 100644 index 0000000000..65dbdb96ae --- /dev/null +++ b/examples/svelte/simple/tsconfig.node.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node" + }, + "include": ["vite.config.ts"] +} diff --git a/examples/svelte/simple/vite.config.ts b/examples/svelte/simple/vite.config.ts new file mode 100644 index 0000000000..401b4d4bd6 --- /dev/null +++ b/examples/svelte/simple/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import { svelte } from '@sveltejs/vite-plugin-svelte' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [svelte()] +}) diff --git a/examples/svelte/star-wars/.gitignore b/examples/svelte/star-wars/.gitignore new file mode 100644 index 0000000000..6fd24c7d48 --- /dev/null +++ b/examples/svelte/star-wars/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example +!lib/ diff --git a/examples/svelte/star-wars/README.md b/examples/svelte/star-wars/README.md new file mode 100644 index 0000000000..b5f81c13d5 --- /dev/null +++ b/examples/svelte/star-wars/README.md @@ -0,0 +1,8 @@ +# Example + +This example is a rewrite of the React Query star-wars example. + +To run this example: + +- `npm install` +- `npm run dev` diff --git a/examples/svelte/star-wars/package.json b/examples/svelte/star-wars/package.json new file mode 100644 index 0000000000..9bf410b1c6 --- /dev/null +++ b/examples/svelte/star-wars/package.json @@ -0,0 +1,27 @@ +{ + "name": "@tanstack/query-example-svelte-star-wars", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json" + }, + "dependencies": { + "@tanstack/svelte-query": "^4.12.0" + }, + "devDependencies": { + "@sveltejs/adapter-auto": "^1.0.0", + "@sveltejs/kit": "^1.0.0", + "autoprefixer": "^10.4.13", + "postcss": "^8.4.20", + "svelte": "^3.54.0", + "svelte-check": "^2.9.2", + "tailwindcss": "^3.2.4", + "tslib": "^2.4.1", + "typescript": "^4.7.4", + "vite": "^4.0.0" + } +} diff --git a/examples/svelte/star-wars/postcss.config.cjs b/examples/svelte/star-wars/postcss.config.cjs new file mode 100644 index 0000000000..116848f66a --- /dev/null +++ b/examples/svelte/star-wars/postcss.config.cjs @@ -0,0 +1,3 @@ +module.exports = { + plugins: [require("tailwindcss"), require("autoprefixer")], +}; diff --git a/examples/svelte/star-wars/src/app.css b/examples/svelte/star-wars/src/app.css new file mode 100644 index 0000000000..317ab3f2d1 --- /dev/null +++ b/examples/svelte/star-wars/src/app.css @@ -0,0 +1,18 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + body { + @apply font-sans; + } + + h1, + h2, + h3, + h4, + h5, + h6 { + @apply font-mono; + } +} diff --git a/examples/svelte/star-wars/src/app.d.ts b/examples/svelte/star-wars/src/app.d.ts new file mode 100644 index 0000000000..1cea0dcf2b --- /dev/null +++ b/examples/svelte/star-wars/src/app.d.ts @@ -0,0 +1,9 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +// and what to do when importing types +declare namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface Platform {} +} diff --git a/examples/svelte/star-wars/src/app.html b/examples/svelte/star-wars/src/app.html new file mode 100644 index 0000000000..d847151a12 --- /dev/null +++ b/examples/svelte/star-wars/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/examples/svelte/star-wars/src/routes/+layout.svelte b/examples/svelte/star-wars/src/routes/+layout.svelte new file mode 100644 index 0000000000..8c5c4a6ef7 --- /dev/null +++ b/examples/svelte/star-wars/src/routes/+layout.svelte @@ -0,0 +1,21 @@ + + + + Svelte Query Star Wars Example + + + + + + diff --git a/examples/svelte/star-wars/src/routes/+page.svelte b/examples/svelte/star-wars/src/routes/+page.svelte new file mode 100644 index 0000000000..eaaf33aa03 --- /dev/null +++ b/examples/svelte/star-wars/src/routes/+page.svelte @@ -0,0 +1,32 @@ +
+

React Query Demo

+

Using the Star Wars API

+

+ (Built by @Brent_m_Clark + ) +

+
+
Why React Query?
+

+ In this demo you will be able to see how React Query is a significant + improvement over redux, mobx, and any + other general-purpose state container. +

+

+ No reducers, thunks, or sagas. No ES6 models to maintain in order to tag + them as observable. +

+

+ Simply associate a key with your fetch call and let{' '} + React Query handle the rest. +

+
Ready to get started?
+

+ Check out the{' '} + Films + and + Characters + ! +

+
+
diff --git a/examples/svelte/star-wars/src/routes/characters/+page.svelte b/examples/svelte/star-wars/src/routes/characters/+page.svelte new file mode 100644 index 0000000000..77f868d693 --- /dev/null +++ b/examples/svelte/star-wars/src/routes/characters/+page.svelte @@ -0,0 +1,36 @@ + + +{#if $query.status === 'loading'} +

Loading...

+{/if} + +{#if $query.status === 'error'} +

Error :(

+{/if} + +{#if $query.status === 'success'} +
+

Characters

+ {#each $query.data.results as person} + {@const personUrlParts = person.url.split('/').filter(Boolean)} + {@const personId = personUrlParts[personUrlParts.length - 1]} + + {/each} +
+{/if} diff --git a/examples/svelte/star-wars/src/routes/characters/[characterId]/+page.svelte b/examples/svelte/star-wars/src/routes/characters/[characterId]/+page.svelte new file mode 100644 index 0000000000..624ee7dece --- /dev/null +++ b/examples/svelte/star-wars/src/routes/characters/[characterId]/+page.svelte @@ -0,0 +1,77 @@ + + +{#if $query.status === 'loading'} +

Loading...

+{/if} + +{#if $query.status === 'error'} +

Error :(

+{/if} + +{#if $query.status === 'success'} + {@const homeworldUrlParts = $query.data.homeworld.split('/').filter(Boolean)} + {@const homeworldId = homeworldUrlParts[homeworldUrlParts.length - 1]} +
+

{$query.data.name}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureValue
Born{$query.data.birth_year}
Eyes{$query.data.eye_color}
Hair{$query.data.hair_color}
Height{$query.data.height}
Mass{$query.data.mass}
Homeworld
+
+

Films

+ {#each $query.data.films as film} + {@const filmUrlParts = film.split('/').filter(Boolean)} + {@const filmId = filmUrlParts[filmUrlParts.length - 1]} + + {/each} +
+{/if} diff --git a/examples/svelte/star-wars/src/routes/characters/[characterId]/+page.ts b/examples/svelte/star-wars/src/routes/characters/[characterId]/+page.ts new file mode 100644 index 0000000000..dbfde8eb56 --- /dev/null +++ b/examples/svelte/star-wars/src/routes/characters/[characterId]/+page.ts @@ -0,0 +1,5 @@ +import type { PageLoad } from './$types' + +export const load: PageLoad = ({ params }) => { + return { params } +} diff --git a/examples/svelte/star-wars/src/routes/characters/[characterId]/Film.svelte b/examples/svelte/star-wars/src/routes/characters/[characterId]/Film.svelte new file mode 100644 index 0000000000..7c0210d8d5 --- /dev/null +++ b/examples/svelte/star-wars/src/routes/characters/[characterId]/Film.svelte @@ -0,0 +1,23 @@ + + +{#if $query.status === 'success'} + +{/if} diff --git a/examples/svelte/star-wars/src/routes/characters/[characterId]/Homeworld.svelte b/examples/svelte/star-wars/src/routes/characters/[characterId]/Homeworld.svelte new file mode 100644 index 0000000000..d931b8cc19 --- /dev/null +++ b/examples/svelte/star-wars/src/routes/characters/[characterId]/Homeworld.svelte @@ -0,0 +1,21 @@ + + +{#if $query.status === 'success'} + + {$query.data.name} + +{/if} diff --git a/examples/svelte/star-wars/src/routes/films/+page.svelte b/examples/svelte/star-wars/src/routes/films/+page.svelte new file mode 100644 index 0000000000..3a7cb24713 --- /dev/null +++ b/examples/svelte/star-wars/src/routes/films/+page.svelte @@ -0,0 +1,41 @@ + + +{#if $query.status === 'loading'} +

Loading...

+{/if} + +{#if $query.status === 'error'} +

Error :(

+{/if} + +{#if $query.status === 'success'} +
+

Films

+ {#each $query.data.results as film} + {@const filmUrlParts = film.url.split('/').filter(Boolean)} + {@const filmId = filmUrlParts[filmUrlParts.length - 1]} + + {/each} +
+{/if} diff --git a/examples/svelte/star-wars/src/routes/films/[filmId]/+page.svelte b/examples/svelte/star-wars/src/routes/films/[filmId]/+page.svelte new file mode 100644 index 0000000000..988ccc6ad5 --- /dev/null +++ b/examples/svelte/star-wars/src/routes/films/[filmId]/+page.svelte @@ -0,0 +1,41 @@ + + +{#if $query.status === 'loading'} +

Loading...

+{/if} + +{#if $query.status === 'error'} +

Error :(

+{/if} + +{#if $query.status === 'success'} +
+

{$query.data.title}

+

{$query.data.opening_crawl}

+
+

Characters

+ {#each $query.data.characters as character} + {@const characterUrlParts = character.split('/').filter(Boolean)} + {@const characterId = characterUrlParts[characterUrlParts.length - 1]} + + {/each} +
+{/if} diff --git a/examples/svelte/star-wars/src/routes/films/[filmId]/+page.ts b/examples/svelte/star-wars/src/routes/films/[filmId]/+page.ts new file mode 100644 index 0000000000..dbfde8eb56 --- /dev/null +++ b/examples/svelte/star-wars/src/routes/films/[filmId]/+page.ts @@ -0,0 +1,5 @@ +import type { PageLoad } from './$types' + +export const load: PageLoad = ({ params }) => { + return { params } +} diff --git a/examples/svelte/star-wars/src/routes/films/[filmId]/Character.svelte b/examples/svelte/star-wars/src/routes/films/[filmId]/Character.svelte new file mode 100644 index 0000000000..b4827ccdf9 --- /dev/null +++ b/examples/svelte/star-wars/src/routes/films/[filmId]/Character.svelte @@ -0,0 +1,23 @@ + + +{#if $query.status === 'success'} + +{/if} diff --git a/examples/svelte/star-wars/static/emblem-light.svg b/examples/svelte/star-wars/static/emblem-light.svg new file mode 100644 index 0000000000..a58e69ad5e --- /dev/null +++ b/examples/svelte/star-wars/static/emblem-light.svg @@ -0,0 +1,13 @@ + + + + emblem-light + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/examples/svelte/star-wars/svelte.config.js b/examples/svelte/star-wars/svelte.config.js new file mode 100644 index 0000000000..a16d0de80a --- /dev/null +++ b/examples/svelte/star-wars/svelte.config.js @@ -0,0 +1,13 @@ +import adapter from '@sveltejs/adapter-auto'; +import { vitePreprocess } from '@sveltejs/kit/vite'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + preprocess: vitePreprocess(), + + kit: { + adapter: adapter() + } +}; + +export default config; diff --git a/examples/svelte/star-wars/tailwind.config.cjs b/examples/svelte/star-wars/tailwind.config.cjs new file mode 100644 index 0000000000..fdcf583098 --- /dev/null +++ b/examples/svelte/star-wars/tailwind.config.cjs @@ -0,0 +1,11 @@ +module.exports = { + content: ["./src/**/*.{html,js,svelte,ts}"], + theme: { + fontFamily: { + sans: + "Roboto, BlinkMacSystemFont, -apple-system, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, Helvetica, Arial, sans-serif", + mono: + "Roboto Mono, BlinkMacSystemFont, -apple-system, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, Helvetica, Arial, sans-serif", + }, + }, +}; diff --git a/examples/svelte/star-wars/tsconfig.json b/examples/svelte/star-wars/tsconfig.json new file mode 100644 index 0000000000..5c56cee332 --- /dev/null +++ b/examples/svelte/star-wars/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true + } +} diff --git a/examples/svelte/star-wars/vite.config.ts b/examples/svelte/star-wars/vite.config.ts new file mode 100644 index 0000000000..096c2069b7 --- /dev/null +++ b/examples/svelte/star-wars/vite.config.ts @@ -0,0 +1,8 @@ +import { sveltekit } from '@sveltejs/kit/vite'; + +/** @type {import('vite').UserConfig} */ +const config = { + plugins: [sveltekit()] +}; + +export default config; diff --git a/package.json b/package.json index af536bf89d..d9f43318c5 100644 --- a/package.json +++ b/package.json @@ -2,17 +2,17 @@ "name": "query", "repository": "https://github.com/tanstack/query.git", "scripts": { - "clean": "pnpm --filter \"./packages/**\" --parallel --no-bail run clean", + "clean": "pnpm --filter \"./packages/**\" --no-bail run clean", "preinstall": "node -e \"if(process.env.CI == 'true') {console.log('Skipping preinstall...'); process.exit(1)}\" || npx -y only-allow pnpm", "install:csb": "pnpm install --frozen-lockfile", "test": "pnpm run test:ci", "test:ci": "pnpm run test:format && pnpm run test:eslint && pnpm run test:jest --collectCoverage false && pnpm run typecheck", - "test:react:17": "pnpm --filter \"./packages/react-*\" --parallel --no-bail run test:jest --collectCoverage false", - "test:eslint": "pnpm --filter \"./packages/**\" --parallel --no-bail run test:eslint", + "test:react:17": "pnpm --filter \"./packages/react-*\" --no-bail run test:jest --collectCoverage false", + "test:eslint": "pnpm --filter \"./packages/**\" --no-bail run test:eslint", "test:format": "pnpm run prettier --check", - "test:jest": "pnpm --filter \"./packages/**\" --parallel --no-bail run test:jest", + "test:jest": "pnpm --filter \"./packages/**\" --no-bail run test:jest", "test:size": "pnpm run build && bundlewatch", - "build": "rollup --config rollup.config.js && pnpm run typecheck && pnpm pnpm --filter \"eslint-plugin-query\" run build && pnpm run build:copyTypes", + "build": "rollup --config rollup.config.js && pnpm run typecheck && pnpm --filter \"@tanstack/eslint-plugin-query\" --filter \"@tanstack/svelte-query\" run build && pnpm run build:copyTypes", "build:copyTypes": "cp packages/react-query-devtools/build/lib/index.d.ts packages/react-query-devtools/build/lib/index.prod.d.ts", "typecheck": "tsc -b", "watch": "concurrently --kill-others \"rollup --config rollup.config.js -w\" \"pnpm run typecheck --watch\"", @@ -37,7 +37,6 @@ "@testing-library/react": "^13.0.0", "@testing-library/react-17": "npm:@testing-library/react@12.1.4", "@testing-library/react-hooks": "^7.0.2", - "@tsconfig/svelte": "^3.0.0", "@types/jest": "^26.0.4", "@types/luxon": "^2.3.1", "@types/node": "^17.0.25", @@ -80,13 +79,11 @@ "react-dom-17": "npm:react-dom@^17.0.2", "rollup": "^2.70.2", "rollup-plugin-size": "^0.2.2", - "rollup-plugin-svelte": "^7.1.0", "rollup-plugin-terser": "^7.0.2", "rollup-plugin-visualizer": "^5.6.0", "solid-js": "^1.5.7", "solid-testing-library": "^0.3.0", "stream-to-array": "^2.3.0", - "svelte": "^3.48.0", "ts-jest": "^27.1.1", "ts-node": "^10.7.0", "typescript": "^4.7.4", diff --git a/packages/svelte-query/.eslintrc b/packages/svelte-query/.eslintrc new file mode 100644 index 0000000000..cc8b7118d3 --- /dev/null +++ b/packages/svelte-query/.eslintrc @@ -0,0 +1,25 @@ +{ + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": "./tsconfig.json", + "sourceType": "module", + "extraFileExtensions": [".svelte"] + }, + "rules": { + "react-hooks/rules-of-hooks": "off" + }, + "extends": [ + "plugin:svelte/recommended", + "../../.eslintrc" + ], + "ignorePatterns": ["*.config.*", "**/build/*", "**/.svelte-kit/*"], + "overrides": [ + { + "files": ["*.svelte"], + "parser": "svelte-eslint-parser", + "parserOptions": { + "parser": "@typescript-eslint/parser" + } + } + ] +} diff --git a/packages/svelte-query/.gitignore b/packages/svelte-query/.gitignore new file mode 100644 index 0000000000..6fd24c7d48 --- /dev/null +++ b/packages/svelte-query/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example +!lib/ diff --git a/packages/svelte-query/package.json b/packages/svelte-query/package.json new file mode 100644 index 0000000000..e1047b82ce --- /dev/null +++ b/packages/svelte-query/package.json @@ -0,0 +1,54 @@ +{ + "name": "@tanstack/svelte-query", + "version": "4.20.0", + "description": "Primitives for managing, caching and syncing asynchronous and remote data in Svelte", + "author": "Dre Johnson", + "license": "MIT", + "repository": "tanstack/query", + "homepage": "https://tanstack.com/query", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "types": "build/lib/index.d.ts", + "module": "build/lib/index.js", + "type": "module", + "scripts": { + "clean": "rimraf ./build", + "build": "svelte-kit sync && svelte-package && rimraf ./build/lib/package.json", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "test:eslint": "svelte-kit sync && ../../node_modules/.bin/eslint --ext .svelte,.ts ./src", + "test:jest": "svelte-kit sync && vitest run --coverage" + }, + "devDependencies": { + "@sveltejs/adapter-auto": "^1.0.0", + "@sveltejs/kit": "^1.0.0", + "@sveltejs/package": "^1.0.0", + "@testing-library/svelte": "^3.2.2", + "@vitest/coverage-istanbul": "^0.26.3", + "eslint-plugin-svelte": "^2.14.1", + "jsdom": "^20.0.3", + "rimraf": "^3.0.2", + "svelte": "^3.54.0", + "svelte-check": "^2.9.2", + "tslib": "^2.4.1", + "typescript": "^4.7.4", + "vite": "^4.0.0", + "vitest": "^0.26.3" + }, + "dependencies": { + "@tanstack/query-core": "workspace:*" + }, + "peerDependencies": { + "svelte": "^3.54.0" + }, + "exports": { + "./package.json": "./package.json", + ".": "./build/lib/index.js" + }, + "svelte": "./build/lib/index.js", + "files": [ + "build/lib/*", + "src" + ] +} diff --git a/packages/svelte-query/src/__tests__/CreateMutation.svelte b/packages/svelte-query/src/__tests__/CreateMutation.svelte new file mode 100644 index 0000000000..88adbe29a2 --- /dev/null +++ b/packages/svelte-query/src/__tests__/CreateMutation.svelte @@ -0,0 +1,13 @@ + + + diff --git a/packages/svelte-query/src/__tests__/CreateQuery.svelte b/packages/svelte-query/src/__tests__/CreateQuery.svelte new file mode 100644 index 0000000000..04c44c1fa3 --- /dev/null +++ b/packages/svelte-query/src/__tests__/CreateQuery.svelte @@ -0,0 +1,23 @@ + + +{#if $query.isLoading} +

Loading

+{:else if $query.isError} +

Error

+{:else if $query.isSuccess} +

Success

+{/if} diff --git a/packages/svelte-query/src/__tests__/createMutation.test.ts b/packages/svelte-query/src/__tests__/createMutation.test.ts new file mode 100644 index 0000000000..a129e5784e --- /dev/null +++ b/packages/svelte-query/src/__tests__/createMutation.test.ts @@ -0,0 +1,22 @@ +import { describe, it, expect, vi } from 'vitest' +import { fireEvent, render, screen } from '@testing-library/svelte' +import CreateMutation from './CreateMutation.svelte' +import { sleep } from './utils' + +describe('createMutation', () => { + it('Call mutate and check function runs', async () => { + const queryFn = vi.fn() + + render(CreateMutation, { + props: { + queryFn, + }, + }) + + fireEvent.click(screen.getByRole('button')) + + await sleep(200) + + expect(queryFn).toHaveBeenCalledTimes(1) + }) +}) diff --git a/packages/svelte-query/src/__tests__/createQuery.test.ts b/packages/svelte-query/src/__tests__/createQuery.test.ts new file mode 100644 index 0000000000..191fea1b23 --- /dev/null +++ b/packages/svelte-query/src/__tests__/createQuery.test.ts @@ -0,0 +1,28 @@ +import { describe, it, expect } from 'vitest' +import { render, screen } from '@testing-library/svelte' +import CreateQuery from './CreateQuery.svelte' +import { sleep } from './utils' + +describe('createQuery', () => { + it('Render and wait for success', async () => { + render(CreateQuery, { + props: { + queryKey: ['test'], + queryFn: async () => { + await sleep(100) + return 'Success' + }, + }, + }) + + expect(screen.queryByText('Loading')).toBeInTheDocument() + expect(screen.queryByText('Error')).not.toBeInTheDocument() + expect(screen.queryByText('Success')).not.toBeInTheDocument() + + await sleep(200) + + expect(screen.queryByText('Success')).toBeInTheDocument() + expect(screen.queryByText('Loading')).not.toBeInTheDocument() + expect(screen.queryByText('Error')).not.toBeInTheDocument() + }) +}) diff --git a/packages/svelte-query/src/__tests__/utils.ts b/packages/svelte-query/src/__tests__/utils.ts new file mode 100644 index 0000000000..9b26cd3ab1 --- /dev/null +++ b/packages/svelte-query/src/__tests__/utils.ts @@ -0,0 +1,72 @@ +import { vi } from 'vitest' +import { act } from '@testing-library/svelte' +import { + QueryClient, + type QueryClientConfig, + type MutationOptions, +} from '../lib' + +export function createQueryClient(config?: QueryClientConfig): QueryClient { + vi.spyOn(console, 'error').mockImplementation(() => undefined) + return new QueryClient({ logger: mockLogger, ...config }) +} + +export function mockVisibilityState(value: DocumentVisibilityState) { + return vi.spyOn(document, 'visibilityState', 'get').mockReturnValue(value) +} + +export function mockNavigatorOnLine(value: boolean) { + return vi.spyOn(navigator, 'onLine', 'get').mockReturnValue(value) +} + +export const mockLogger = { + log: vi.fn(), + warn: vi.fn(), + error: vi.fn(), +} + +let queryKeyCount = 0 +export function queryKey(): Array { + queryKeyCount++ + return [`query_${queryKeyCount}`] +} + +export function sleep(timeout: number): Promise { + return new Promise((resolve, _reject) => { + setTimeout(resolve, timeout) + }) +} + +export async function simplefetcher() { + await sleep(10) + return 'test' +} + +export function setActTimeout(fn: () => void, ms?: number) { + return setTimeout(() => { + act(() => { + fn() + }) + }, ms) +} + +/** + * Assert the parameter is of a specific type. + */ +export function expectType(_: T): void { + return undefined +} + +/** + * Assert the parameter is not typed as `any` + */ +export function expectTypeNotAny(_: 0 extends 1 & T ? never : T): void { + return undefined +} + +export function executeMutation( + queryClient: QueryClient, + options: MutationOptions, +): Promise { + return queryClient.getMutationCache().build(queryClient, options).execute() +} diff --git a/packages/svelte-query/src/lib/Hydrate.svelte b/packages/svelte-query/src/lib/Hydrate.svelte new file mode 100644 index 0000000000..de3e6ca7c1 --- /dev/null +++ b/packages/svelte-query/src/lib/Hydrate.svelte @@ -0,0 +1,11 @@ + + + diff --git a/packages/svelte-query/src/lib/QueryClientProvider.svelte b/packages/svelte-query/src/lib/QueryClientProvider.svelte new file mode 100644 index 0000000000..86ce96ecea --- /dev/null +++ b/packages/svelte-query/src/lib/QueryClientProvider.svelte @@ -0,0 +1,19 @@ + + + diff --git a/packages/svelte-query/src/lib/context.ts b/packages/svelte-query/src/lib/context.ts new file mode 100644 index 0000000000..d907da4732 --- /dev/null +++ b/packages/svelte-query/src/lib/context.ts @@ -0,0 +1,21 @@ +import { setContext, getContext } from 'svelte' +import type { QueryClient } from '@tanstack/query-core' + +const _contextKey = '$$_queryClient' + +/** Retrieves a Client from Svelte's context */ +export const getQueryClientContext = (): QueryClient => { + const client = getContext(_contextKey) + if (!client) { + throw new Error( + 'No QueryClient was found in Svelte context. Did you forget to wrap your component with QueryClientProvider?', + ) + } + + return client as QueryClient +} + +/** Sets a QueryClient on Svelte's context */ +export const setQueryClientContext = (client: QueryClient): void => { + setContext(_contextKey, client) +} diff --git a/packages/svelte-query/src/lib/createBaseQuery.ts b/packages/svelte-query/src/lib/createBaseQuery.ts new file mode 100644 index 0000000000..0948911537 --- /dev/null +++ b/packages/svelte-query/src/lib/createBaseQuery.ts @@ -0,0 +1,76 @@ +import { + notifyManager, + type QueryKey, + type QueryObserver, +} from '@tanstack/query-core' +import type { CreateBaseQueryOptions } from './types' +import { useQueryClient } from './useQueryClient' +import { derived, readable } from 'svelte/store' + +export function createBaseQuery< + TQueryFnData, + TError, + TData, + TQueryData, + TQueryKey extends QueryKey, +>( + options: CreateBaseQueryOptions< + TQueryFnData, + TError, + TData, + TQueryData, + TQueryKey + >, + Observer: typeof QueryObserver, +) { + const queryClient = useQueryClient() + const defaultedOptions = queryClient.defaultQueryOptions(options) + defaultedOptions._optimisticResults = 'optimistic' + + let observer = new Observer< + TQueryFnData, + TError, + TData, + TQueryData, + TQueryKey + >(queryClient, defaultedOptions) + + // Include callbacks in batch renders + if (defaultedOptions.onError) { + defaultedOptions.onError = notifyManager.batchCalls( + defaultedOptions.onError, + ) + } + + if (defaultedOptions.onSuccess) { + defaultedOptions.onSuccess = notifyManager.batchCalls( + defaultedOptions.onSuccess, + ) + } + + if (defaultedOptions.onSettled) { + defaultedOptions.onSettled = notifyManager.batchCalls( + defaultedOptions.onSettled, + ) + } + + readable(observer).subscribe(($observer) => { + observer = $observer + // Do not notify on updates because of changes in the options because + // these changes should already be reflected in the optimistic result. + observer.setOptions(defaultedOptions, { listeners: false }) + }) + + const result = readable(observer.getCurrentResult(), (set) => { + return observer.subscribe(notifyManager.batchCalls(set)) + }) + + const { subscribe } = derived(result, ($result) => { + $result = observer.getOptimisticResult(defaultedOptions) + return !defaultedOptions.notifyOnChangeProps + ? observer.trackResult($result) + : $result + }) + + return { subscribe } +} diff --git a/packages/svelte-query/src/lib/createInfiniteQuery.ts b/packages/svelte-query/src/lib/createInfiniteQuery.ts new file mode 100644 index 0000000000..83683769b7 --- /dev/null +++ b/packages/svelte-query/src/lib/createInfiniteQuery.ts @@ -0,0 +1,103 @@ +import { + InfiniteQueryObserver, + parseQueryArgs, + type QueryObserver, + type QueryFunction, + type QueryKey, +} from '@tanstack/query-core' +import type { + CreateInfiniteQueryOptions, + CreateInfiniteQueryResult, +} from './types' +import { createBaseQuery } from './createBaseQuery' + +export function createInfiniteQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + options: CreateInfiniteQueryOptions< + TQueryFnData, + TError, + TData, + TQueryFnData, + TQueryKey + >, +): CreateInfiniteQueryResult +export function createInfiniteQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + queryKey: TQueryKey, + options?: Omit< + CreateInfiniteQueryOptions< + TQueryFnData, + TError, + TData, + TQueryFnData, + TQueryKey + >, + 'queryKey' + >, +): CreateInfiniteQueryResult +export function createInfiniteQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + queryKey: TQueryKey, + queryFn: QueryFunction, + options?: Omit< + CreateInfiniteQueryOptions< + TQueryFnData, + TError, + TData, + TQueryFnData, + TQueryKey + >, + 'queryKey' | 'queryFn' + >, +): CreateInfiniteQueryResult + +export function createInfiniteQuery< + TQueryFnData, + TError, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + arg1: + | TQueryKey + | CreateInfiniteQueryOptions< + TQueryFnData, + TError, + TData, + TQueryFnData, + TQueryKey + >, + arg2?: + | QueryFunction + | CreateInfiniteQueryOptions< + TQueryFnData, + TError, + TData, + TQueryFnData, + TQueryKey + >, + arg3?: CreateInfiniteQueryOptions< + TQueryFnData, + TError, + TData, + TQueryFnData, + TQueryKey + >, +): CreateInfiniteQueryResult { + const options = parseQueryArgs(arg1, arg2, arg3) + return createBaseQuery( + options, + InfiniteQueryObserver as typeof QueryObserver, + ) as CreateInfiniteQueryResult +} diff --git a/packages/svelte-query/src/lib/createMutation.ts b/packages/svelte-query/src/lib/createMutation.ts new file mode 100644 index 0000000000..f2cc43e3f3 --- /dev/null +++ b/packages/svelte-query/src/lib/createMutation.ts @@ -0,0 +1,110 @@ +import { readable, derived } from 'svelte/store' +import { + type MutationFunction, + type MutationKey, + MutationObserver, + notifyManager, + parseMutationArgs, +} from '@tanstack/query-core' +import type { + UseMutateFunction, + CreateMutationOptions, + MutationStoreResult, +} from './types' +import { useQueryClient } from './useQueryClient' + +export function createMutation< + TData = unknown, + TError = unknown, + TVariables = unknown, + TContext = unknown, +>( + options: CreateMutationOptions, +): MutationStoreResult + +export function createMutation< + TData = unknown, + TError = unknown, + TVariables = unknown, + TContext = unknown, +>( + mutationFn: MutationFunction, + options?: Omit< + CreateMutationOptions, + 'mutationFn' + >, +): MutationStoreResult + +export function createMutation< + TData = unknown, + TError = unknown, + TVariables = unknown, + TContext = unknown, +>( + mutationKey: MutationKey, + options?: Omit< + CreateMutationOptions, + 'mutationKey' + >, +): MutationStoreResult + +export function createMutation< + TData = unknown, + TError = unknown, + TVariables = unknown, + TContext = unknown, +>( + mutationKey: MutationKey, + mutationFn?: MutationFunction, + options?: Omit< + CreateMutationOptions, + 'mutationKey' | 'mutationFn' + >, +): MutationStoreResult + +export function createMutation< + TData = unknown, + TError = unknown, + TVariables = unknown, + TContext = unknown, +>( + arg1: + | MutationKey + | MutationFunction + | CreateMutationOptions, + arg2?: + | MutationFunction + | CreateMutationOptions, + arg3?: CreateMutationOptions, +): MutationStoreResult { + const options = parseMutationArgs(arg1, arg2, arg3) + const queryClient = useQueryClient() + let observer = new MutationObserver( + queryClient, + options, + ) + let mutate: UseMutateFunction + + readable(observer).subscribe(($observer) => { + observer = $observer + mutate = (variables, mutateOptions) => { + observer.mutate(variables, mutateOptions).catch(noop) + } + observer.setOptions(options) + }) + + const result = readable(observer.getCurrentResult(), (set) => { + return observer.subscribe(notifyManager.batchCalls((val) => set(val))) + }) + + const { subscribe } = derived(result, ($result) => ({ + ...$result, + mutate, + mutateAsync: $result.mutate, + })) + + return { subscribe } +} + +// eslint-disable-next-line @typescript-eslint/no-empty-function +function noop() {} diff --git a/packages/svelte-query/src/lib/createQueries.ts b/packages/svelte-query/src/lib/createQueries.ts new file mode 100644 index 0000000000..4624ae6638 --- /dev/null +++ b/packages/svelte-query/src/lib/createQueries.ts @@ -0,0 +1,178 @@ +import type { QueryKey, QueryFunction, QueryClient } from '@tanstack/query-core' + +import { notifyManager, QueriesObserver } from '@tanstack/query-core' +import { readable, type Readable } from 'svelte/store' + +import type { CreateQueryOptions, CreateQueryResult } from './types' +import { useQueryClient } from './useQueryClient' + +// This defines the `CreateQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`. +// - `context` is omitted as it is passed as a root-level option to `createQueries` instead. +type CreateQueryOptionsForCreateQueries< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +> = Omit, 'context'> + +// Avoid TS depth-limit error in case of large array literal +type MAXIMUM_DEPTH = 20 + +type GetOptions = + // Part 1: responsible for applying explicit type parameter to function arguments, if object { queryFnData: TQueryFnData, error: TError, data: TData } + T extends { + queryFnData: infer TQueryFnData + error?: infer TError + data: infer TData + } + ? CreateQueryOptionsForCreateQueries + : T extends { queryFnData: infer TQueryFnData; error?: infer TError } + ? CreateQueryOptionsForCreateQueries + : T extends { data: infer TData; error?: infer TError } + ? CreateQueryOptionsForCreateQueries + : // Part 2: responsible for applying explicit type parameter to function arguments, if tuple [TQueryFnData, TError, TData] + T extends [infer TQueryFnData, infer TError, infer TData] + ? CreateQueryOptionsForCreateQueries + : T extends [infer TQueryFnData, infer TError] + ? CreateQueryOptionsForCreateQueries + : T extends [infer TQueryFnData] + ? CreateQueryOptionsForCreateQueries + : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided + T extends { + queryFn?: QueryFunction + select: (data: any) => infer TData + } + ? CreateQueryOptionsForCreateQueries< + TQueryFnData, + unknown, + TData, + TQueryKey + > + : T extends { queryFn?: QueryFunction } + ? CreateQueryOptionsForCreateQueries< + TQueryFnData, + unknown, + TQueryFnData, + TQueryKey + > + : // Fallback + CreateQueryOptionsForCreateQueries + +type GetResults = + // Part 1: responsible for mapping explicit type parameter to function result, if object + T extends { queryFnData: any; error?: infer TError; data: infer TData } + ? CreateQueryResult + : T extends { queryFnData: infer TQueryFnData; error?: infer TError } + ? CreateQueryResult + : T extends { data: infer TData; error?: infer TError } + ? CreateQueryResult + : // Part 2: responsible for mapping explicit type parameter to function result, if tuple + T extends [any, infer TError, infer TData] + ? CreateQueryResult + : T extends [infer TQueryFnData, infer TError] + ? CreateQueryResult + : T extends [infer TQueryFnData] + ? CreateQueryResult + : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided + T extends { + queryFn?: QueryFunction + select: (data: any) => infer TData + } + ? CreateQueryResult + : T extends { queryFn?: QueryFunction } + ? CreateQueryResult + : // Fallback + CreateQueryResult + +/** + * QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param + */ +export type QueriesOptions< + T extends any[], + Result extends any[] = [], + Depth extends ReadonlyArray = [], +> = Depth['length'] extends MAXIMUM_DEPTH + ? CreateQueryOptionsForCreateQueries[] + : T extends [] + ? [] + : T extends [infer Head] + ? [...Result, GetOptions] + : T extends [infer Head, ...infer Tail] + ? QueriesOptions<[...Tail], [...Result, GetOptions], [...Depth, 1]> + : unknown[] extends T + ? T + : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/homogenous type! + // use this to infer the param types in the case of Array.map() argument + T extends CreateQueryOptionsForCreateQueries< + infer TQueryFnData, + infer TError, + infer TData, + infer TQueryKey + >[] + ? CreateQueryOptionsForCreateQueries[] + : // Fallback + CreateQueryOptionsForCreateQueries[] + +/** + * QueriesResults reducer recursively maps type param to results + */ +export type QueriesResults< + T extends any[], + Result extends any[] = [], + Depth extends ReadonlyArray = [], +> = Depth['length'] extends MAXIMUM_DEPTH + ? CreateQueryResult[] + : T extends [] + ? [] + : T extends [infer Head] + ? [...Result, GetResults] + : T extends [infer Head, ...infer Tail] + ? QueriesResults<[...Tail], [...Result, GetResults], [...Depth, 1]> + : T extends CreateQueryOptionsForCreateQueries< + infer TQueryFnData, + infer TError, + infer TData, + any + >[] + ? // Dynamic-size (homogenous) CreateQueryOptions array: map directly to array of results + CreateQueryResult[] + : // Fallback + CreateQueryResult[] + +export type CreateQueriesResult = Readable> + +export function createQueries( + queries: readonly [...QueriesOptions], +): CreateQueriesResult { + const client: QueryClient = useQueryClient() + // const isRestoring = useIsRestoring() + + function getDefaultQuery(newQueries: readonly [...QueriesOptions]) { + return newQueries.map((options) => { + const defaultedOptions = client.defaultQueryOptions(options) + // Make sure the results are already in fetching state before subscribing or updating options + defaultedOptions._optimisticResults = 'optimistic' + + return defaultedOptions + }) + } + + const defaultedQueries = getDefaultQuery(queries) + let observer = new QueriesObserver(client, defaultedQueries) + + readable(observer).subscribe(($observer) => { + observer = $observer + // Do not notify on updates because of changes in the options because + // these changes should already be reflected in the optimistic result. + observer.setQueries(defaultedQueries, { listeners: false }) + }) + + const { subscribe } = readable( + observer.getOptimisticResult(defaultedQueries) as any, + (set) => { + return observer.subscribe(notifyManager.batchCalls(set)) + }, + ) + + return { subscribe } +} diff --git a/packages/svelte-query/src/lib/createQuery.ts b/packages/svelte-query/src/lib/createQuery.ts new file mode 100644 index 0000000000..fcfa873943 --- /dev/null +++ b/packages/svelte-query/src/lib/createQuery.ts @@ -0,0 +1,143 @@ +import { QueryObserver, parseQueryArgs } from '@tanstack/query-core' +import type { QueryFunction, QueryKey } from '@tanstack/query-core' +import { createBaseQuery } from './createBaseQuery' +import type { + DefinedCreateQueryResult, + CreateQueryOptions, + CreateQueryStoreResult, +} from './types' + +export function createQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + options: Omit< + CreateQueryOptions, + 'initialData' + > & { + initialData?: () => undefined + }, +): CreateQueryStoreResult + +export function createQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + options: Omit< + CreateQueryOptions, + 'initialData' + > & { + initialData: TQueryFnData | (() => TQueryFnData) + }, +): DefinedCreateQueryResult + +export function createQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + options: CreateQueryOptions, +): CreateQueryStoreResult + +export function createQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + queryKey: TQueryKey, + options?: Omit< + CreateQueryOptions, + 'queryKey' | 'initialData' + > & { initialData?: () => undefined }, +): CreateQueryStoreResult + +export function createQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + queryKey: TQueryKey, + options?: Omit< + CreateQueryOptions, + 'queryKey' | 'initialData' + > & { initialData: TQueryFnData | (() => TQueryFnData) }, +): DefinedCreateQueryResult + +export function createQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + queryKey: TQueryKey, + options?: Omit< + CreateQueryOptions, + 'queryKey' + >, +): CreateQueryStoreResult + +export function createQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + queryKey: TQueryKey, + queryFn: QueryFunction, + options?: Omit< + CreateQueryOptions, + 'queryKey' | 'queryFn' | 'initialData' + > & { initialData?: () => undefined }, +): CreateQueryStoreResult + +export function createQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + queryKey: TQueryKey, + queryFn: QueryFunction, + options?: Omit< + CreateQueryOptions, + 'queryKey' | 'queryFn' | 'initialData' + > & { initialData: TQueryFnData | (() => TQueryFnData) }, +): DefinedCreateQueryResult + +export function createQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + queryKey: TQueryKey, + queryFn: QueryFunction, + options?: Omit< + CreateQueryOptions, + 'queryKey' | 'queryFn' + >, +): CreateQueryStoreResult + +export function createQuery< + TQueryFnData, + TError, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +>( + arg1: TQueryKey | CreateQueryOptions, + arg2?: + | QueryFunction + | CreateQueryOptions, + arg3?: CreateQueryOptions, +): CreateQueryStoreResult { + const parsedOptions = parseQueryArgs(arg1, arg2, arg3) + const result = createBaseQuery(parsedOptions, QueryObserver) + return result +} diff --git a/packages/svelte-query/src/lib/index.ts b/packages/svelte-query/src/lib/index.ts new file mode 100644 index 0000000000..4df44dd40f --- /dev/null +++ b/packages/svelte-query/src/lib/index.ts @@ -0,0 +1,17 @@ +/* istanbul ignore file */ + +// Re-export core +export * from '@tanstack/query-core' + +// Svelte Query +export * from './types' +export { createQuery } from './createQuery' +export { createQueries } from './createQueries' +export { createInfiniteQuery } from './createInfiniteQuery' +export { createMutation } from './createMutation' +export { useQueryClient } from './useQueryClient' +export { useIsFetching } from './useIsFetching' +export { useIsMutating } from './useIsMutating' +export { useHydrate } from './useHydrate' +export { default as Hydrate } from './Hydrate.svelte' +export { default as QueryClientProvider } from './QueryClientProvider.svelte' diff --git a/packages/svelte-query/src/lib/types.ts b/packages/svelte-query/src/lib/types.ts new file mode 100644 index 0000000000..032ae6cd7d --- /dev/null +++ b/packages/svelte-query/src/lib/types.ts @@ -0,0 +1,146 @@ +import type { + InfiniteQueryObserverOptions, + InfiniteQueryObserverResult, + MutationObserverResult, + QueryObserverOptions, + QueryObserverResult, + QueryKey, + MutationObserverOptions, + MutateFunction, + DefinedQueryObserverResult, +} from '@tanstack/query-core' +import type { QueryClient } from '@tanstack/query-core' +import type { Readable } from 'svelte/store' + +export interface ContextOptions { + /** + * Use this to pass your Svelte Query context. Otherwise, `defaultContext` will be used. + */ + context?: QueryClient | undefined +} + +export interface CreateBaseQueryOptions< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +> extends ContextOptions, + QueryObserverOptions {} + +export interface CreateQueryOptions< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +> extends CreateBaseQueryOptions< + TQueryFnData, + TError, + TData, + TQueryFnData, + TQueryKey + > {} + +export interface CreateInfiniteQueryOptions< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +> extends InfiniteQueryObserverOptions< + TQueryFnData, + TError, + TData, + TQueryData, + TQueryKey + > {} + +export type CreateInfiniteQueryResult< + TData = unknown, + TError = unknown, +> = Readable> + +export interface CreateInfiniteQueryStoreResult< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, +> extends Readable> {} + +export type CreateBaseQueryResult< + TData = unknown, + TError = unknown, +> = QueryObserverResult + +export type CreateQueryResult< + TData = unknown, + TError = unknown, +> = CreateBaseQueryResult + +export interface CreateQueryStoreResult< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, +> extends Readable> {} + +export type DefinedCreateBaseQueryResult< + TData = unknown, + TError = unknown, +> = Readable> + +export type DefinedCreateQueryResult< + TData = unknown, + TError = unknown, +> = DefinedCreateBaseQueryResult + +export interface CreateMutationOptions< + TData = unknown, + TError = unknown, + TVariables = void, + TContext = unknown, +> extends ContextOptions, + Omit< + MutationObserverOptions, + '_defaulted' | 'variables' + > {} + +export type UseMutateFunction< + TData = unknown, + TError = unknown, + TVariables = void, + TContext = unknown, +> = ( + ...args: Parameters> +) => void + +export type UseMutateAsyncFunction< + TData = unknown, + TError = unknown, + TVariables = void, + TContext = unknown, +> = MutateFunction + +export type UseBaseMutationResult< + TData = unknown, + TError = unknown, + TVariables = unknown, + TContext = unknown, +> = Override< + MutationObserverResult, + { mutate: UseMutateFunction } +> & { mutateAsync: UseMutateAsyncFunction } + +export type CreateMutationResult< + TData = unknown, + TError = unknown, + TVariables = unknown, + TContext = unknown, +> = UseBaseMutationResult + +export interface MutationStoreResult< + TData = unknown, + TError = unknown, + TVariables = unknown, + TContext = unknown, +> extends Readable> {} + +type Override = { [K in keyof A]: K extends keyof B ? B[K] : A[K] } diff --git a/packages/svelte-query/src/lib/useHydrate.ts b/packages/svelte-query/src/lib/useHydrate.ts new file mode 100644 index 0000000000..64eb6f3ff0 --- /dev/null +++ b/packages/svelte-query/src/lib/useHydrate.ts @@ -0,0 +1,14 @@ +import { + type HydrateOptions, + type QueryClient, + hydrate, +} from '@tanstack/query-core' +import { useQueryClient } from './useQueryClient' + +export function useHydrate(state?: unknown, options?: HydrateOptions) { + const client: QueryClient = useQueryClient() + + if (state) { + hydrate(client, state, options) + } +} diff --git a/packages/svelte-query/src/lib/useIsFetching.ts b/packages/svelte-query/src/lib/useIsFetching.ts new file mode 100644 index 0000000000..e0f8aea5e9 --- /dev/null +++ b/packages/svelte-query/src/lib/useIsFetching.ts @@ -0,0 +1,41 @@ +import { + type QueryFilters, + type QueryKey, + type QueryClient, + parseFilterArgs, + notifyManager, +} from '@tanstack/query-core' +import { type Readable, readable } from 'svelte/store' +import { useQueryClient } from './useQueryClient' + +export function useIsFetching(filters?: QueryFilters): Readable +export function useIsFetching( + queryKey?: QueryKey, + filters?: QueryFilters, +): Readable + +export function useIsFetching( + arg1?: QueryKey | QueryFilters, + arg2?: QueryFilters, +): Readable { + const [filters] = parseFilterArgs(arg1, arg2) + const client: QueryClient = useQueryClient() + const cache = client.getQueryCache() + // isFetching is the prev value initialized on mount * + let isFetching = client.isFetching(filters) + + const { subscribe } = readable(isFetching, (set) => { + return cache.subscribe( + notifyManager.batchCalls(() => { + const newIsFetching = client.isFetching(filters) + if (isFetching !== newIsFetching) { + // * and update with each change + isFetching = newIsFetching + set(isFetching) + } + }), + ) + }) + + return { subscribe } +} diff --git a/packages/svelte-query/src/lib/useIsMutating.ts b/packages/svelte-query/src/lib/useIsMutating.ts new file mode 100644 index 0000000000..a743d82c15 --- /dev/null +++ b/packages/svelte-query/src/lib/useIsMutating.ts @@ -0,0 +1,41 @@ +import { + type MutationFilters, + type MutationKey, + type QueryClient, + notifyManager, + parseMutationFilterArgs, +} from '@tanstack/query-core' +import { type Readable, readable } from 'svelte/store' +import { useQueryClient } from './useQueryClient' + +export function useIsMutating(filters?: MutationFilters): Readable +export function useIsMutating( + mutationKey?: MutationKey, + filters?: Omit, +): Readable + +export function useIsMutating( + arg1?: MutationKey | MutationFilters, + arg2?: Omit, +): Readable { + const [filters] = parseMutationFilterArgs(arg1, arg2) + const client: QueryClient = useQueryClient() + const cache = client.getMutationCache() + // isMutating is the prev value initialized on mount * + let isMutating = client.isMutating(filters) + + const { subscribe } = readable(isMutating, (set) => { + return cache.subscribe( + notifyManager.batchCalls(() => { + const newIisMutating = client.isMutating(filters) + if (isMutating !== newIisMutating) { + // * and update with each change + isMutating = newIisMutating + set(isMutating) + } + }), + ) + }) + + return { subscribe } +} diff --git a/packages/svelte-query/src/lib/useQueryClient.ts b/packages/svelte-query/src/lib/useQueryClient.ts new file mode 100644 index 0000000000..ed725c8926 --- /dev/null +++ b/packages/svelte-query/src/lib/useQueryClient.ts @@ -0,0 +1,7 @@ +import type { QueryClient } from '@tanstack/query-core' +import { getQueryClientContext } from './context' + +export function useQueryClient(): QueryClient { + const queryClient = getQueryClientContext() + return queryClient +} diff --git a/packages/svelte-query/static/emblem-light.svg b/packages/svelte-query/static/emblem-light.svg new file mode 100644 index 0000000000..a58e69ad5e --- /dev/null +++ b/packages/svelte-query/static/emblem-light.svg @@ -0,0 +1,13 @@ + + + + emblem-light + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/packages/svelte-query/svelte.config.js b/packages/svelte-query/svelte.config.js new file mode 100644 index 0000000000..83eca34d16 --- /dev/null +++ b/packages/svelte-query/svelte.config.js @@ -0,0 +1,16 @@ +import adapter from '@sveltejs/adapter-auto'; +import { vitePreprocess } from '@sveltejs/kit/vite'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + preprocess: vitePreprocess(), + kit: { + adapter: adapter() + }, + package: { + source: "./src/lib", + dir: "./build/lib" + } +}; + +export default config; diff --git a/packages/svelte-query/tsconfig.json b/packages/svelte-query/tsconfig.json new file mode 100644 index 0000000000..737686c2a4 --- /dev/null +++ b/packages/svelte-query/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true + } +} diff --git a/packages/svelte-query/vite.config.ts b/packages/svelte-query/vite.config.ts new file mode 100644 index 0000000000..aabb820566 --- /dev/null +++ b/packages/svelte-query/vite.config.ts @@ -0,0 +1,22 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import path from 'path'; +import type { UserConfig } from 'vite'; + +const config: UserConfig = { + plugins: [sveltekit()], + resolve: { + alias: { + "@tanstack/query-core": path.resolve(__dirname, '..', 'query-core', 'src'), + } + }, + test: { + coverage: { + provider: 'istanbul' + }, + environment: 'jsdom', + include: ['src/**/*.{test,spec}.{js,ts}'], + setupFiles: ['vitest.setup.ts'] + } +}; + +export default config; diff --git a/packages/svelte-query/vitest.setup.ts b/packages/svelte-query/vitest.setup.ts new file mode 100644 index 0000000000..b210af530c --- /dev/null +++ b/packages/svelte-query/vitest.setup.ts @@ -0,0 +1,4 @@ +import matchers from '@testing-library/jest-dom/matchers'; +import { expect } from 'vitest'; + +expect.extend(matchers); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a84457bef4..bd351508ef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,7 +18,6 @@ importers: '@testing-library/react': ^13.0.0 '@testing-library/react-17': npm:@testing-library/react@12.1.4 '@testing-library/react-hooks': ^7.0.2 - '@tsconfig/svelte': ^3.0.0 '@types/jest': ^26.0.4 '@types/luxon': ^2.3.1 '@types/node': ^17.0.25 @@ -61,13 +60,11 @@ importers: react-dom-17: npm:react-dom@^17.0.2 rollup: ^2.70.2 rollup-plugin-size: ^0.2.2 - rollup-plugin-svelte: ^7.1.0 rollup-plugin-terser: ^7.0.2 rollup-plugin-visualizer: ^5.6.0 solid-js: ^1.5.7 solid-testing-library: ^0.3.0 stream-to-array: ^2.3.0 - svelte: ^3.48.0 ts-jest: ^27.1.1 ts-node: ^10.7.0 typescript: ^4.7.4 @@ -87,7 +84,6 @@ importers: '@testing-library/react': 13.3.0_biqbaboplfbrettd7655fr4n2y '@testing-library/react-17': /@testing-library/react/12.1.4_biqbaboplfbrettd7655fr4n2y '@testing-library/react-hooks': 7.0.2_biqbaboplfbrettd7655fr4n2y - '@tsconfig/svelte': 3.0.0 '@types/jest': 26.0.24 '@types/luxon': 2.3.2 '@types/node': 17.0.45 @@ -130,13 +126,11 @@ importers: react-dom-17: /react-dom/17.0.2_react@18.2.0 rollup: 2.78.1 rollup-plugin-size: 0.2.2 - rollup-plugin-svelte: 7.1.0_7rgskvp3hfjz55pue4td2a2xga rollup-plugin-terser: 7.0.2_rollup@2.78.1 rollup-plugin-visualizer: 5.6.0_rollup@2.78.1 solid-js: 1.5.7 solid-testing-library: 0.3.0_solid-js@1.5.7 stream-to-array: 2.3.0 - svelte: 3.49.0 ts-jest: 27.1.5_kv3z5ukkp6hjlassekz7vtidta ts-node: 10.8.2_rb7lfb2dlgdf5f7m6mcvvespxa typescript: 4.8.3 @@ -642,6 +636,192 @@ importers: vite: 3.1.3 vite-plugin-solid: 2.3.9_solid-js@1.5.4+vite@3.1.3 + examples/svelte/auto-refetching: + specifiers: + '@sveltejs/adapter-auto': ^1.0.0 + '@sveltejs/kit': ^1.0.0 + '@tanstack/svelte-query': ^4.12.0 + svelte: ^3.54.0 + svelte-check: ^2.9.2 + svelte-preprocess: ^4.10.7 + tslib: ^2.4.1 + typescript: ^4.7.4 + vite: ^4.0.0 + dependencies: + '@tanstack/svelte-query': link:../../../packages/svelte-query + devDependencies: + '@sveltejs/adapter-auto': 1.0.0_@sveltejs+kit@1.0.7 + '@sveltejs/kit': 1.0.7_svelte@3.55.0+vite@4.0.4 + svelte: 3.55.0 + svelte-check: 2.10.3_svelte@3.55.0 + svelte-preprocess: 4.10.7_glsdxddlaertg66rhhvanbinpy + tslib: 2.4.1 + typescript: 4.8.4 + vite: 4.0.4 + + examples/svelte/basic: + specifiers: + '@sveltejs/vite-plugin-svelte': ^1.0.2 + '@tanstack/svelte-query': ^4.12.0 + '@tsconfig/svelte': ^3.0.0 + svelte: ^3.54.0 + svelte-check: ^2.9.2 + svelte-preprocess: ^4.10.7 + tslib: ^2.4.1 + typescript: ^4.7.4 + vite: ^3.1.0 + dependencies: + '@tanstack/svelte-query': link:../../../packages/svelte-query + devDependencies: + '@sveltejs/vite-plugin-svelte': 1.4.0_svelte@3.55.0+vite@3.2.2 + '@tsconfig/svelte': 3.0.0 + svelte: 3.55.0 + svelte-check: 2.10.3_svelte@3.55.0 + svelte-preprocess: 4.10.7_glsdxddlaertg66rhhvanbinpy + tslib: 2.4.1 + typescript: 4.8.4 + vite: 3.2.2 + + examples/svelte/hydration: + specifiers: + '@sveltejs/adapter-auto': ^1.0.0 + '@sveltejs/kit': ^1.0.0 + '@tanstack/svelte-query': ^4.12.0 + svelte: ^3.54.0 + svelte-check: ^2.9.2 + svelte-preprocess: ^4.10.7 + tslib: ^2.4.1 + typescript: ^4.7.4 + vite: ^4.0.0 + dependencies: + '@tanstack/svelte-query': link:../../../packages/svelte-query + devDependencies: + '@sveltejs/adapter-auto': 1.0.0_@sveltejs+kit@1.0.7 + '@sveltejs/kit': 1.0.7_svelte@3.55.0+vite@4.0.4 + svelte: 3.55.0 + svelte-check: 2.10.3_svelte@3.55.0 + svelte-preprocess: 4.10.7_glsdxddlaertg66rhhvanbinpy + tslib: 2.4.1 + typescript: 4.8.4 + vite: 4.0.4 + + examples/svelte/infinite-loadmore: + specifiers: + '@sveltejs/vite-plugin-svelte': ^1.0.2 + '@tanstack/svelte-query': ^4.12.0 + '@tsconfig/svelte': ^3.0.0 + svelte: ^3.54.0 + svelte-check: ^2.9.2 + svelte-preprocess: ^4.10.7 + tslib: ^2.4.1 + typescript: ^4.7.4 + vite: ^3.1.0 + dependencies: + '@tanstack/svelte-query': link:../../../packages/svelte-query + devDependencies: + '@sveltejs/vite-plugin-svelte': 1.4.0_svelte@3.55.0+vite@3.2.2 + '@tsconfig/svelte': 3.0.0 + svelte: 3.55.0 + svelte-check: 2.10.3_svelte@3.55.0 + svelte-preprocess: 4.10.7_glsdxddlaertg66rhhvanbinpy + tslib: 2.4.1 + typescript: 4.8.4 + vite: 3.2.2 + + examples/svelte/optimistic-updates-typescript: + specifiers: + '@sveltejs/adapter-auto': ^1.0.0 + '@sveltejs/kit': ^1.0.0 + '@tanstack/svelte-query': ^4.12.0 + svelte: ^3.54.0 + svelte-check: ^2.9.2 + svelte-preprocess: ^4.10.7 + tslib: ^2.4.1 + typescript: ^4.7.4 + vite: ^4.0.0 + dependencies: + '@tanstack/svelte-query': link:../../../packages/svelte-query + devDependencies: + '@sveltejs/adapter-auto': 1.0.0_@sveltejs+kit@1.0.7 + '@sveltejs/kit': 1.0.7_svelte@3.55.0+vite@4.0.4 + svelte: 3.55.0 + svelte-check: 2.10.3_svelte@3.55.0 + svelte-preprocess: 4.10.7_glsdxddlaertg66rhhvanbinpy + tslib: 2.4.1 + typescript: 4.8.4 + vite: 4.0.4 + + examples/svelte/playground: + specifiers: + '@sveltejs/adapter-auto': ^1.0.0 + '@sveltejs/kit': ^1.0.0 + '@tanstack/svelte-query': ^4.12.0 + svelte: ^3.54.0 + svelte-check: ^2.9.2 + tslib: ^2.4.1 + typescript: ^4.7.4 + vite: ^4.0.0 + dependencies: + '@tanstack/svelte-query': link:../../../packages/svelte-query + devDependencies: + '@sveltejs/adapter-auto': 1.0.0_@sveltejs+kit@1.0.7 + '@sveltejs/kit': 1.0.7_svelte@3.55.0+vite@4.0.4 + svelte: 3.55.0 + svelte-check: 2.10.3_svelte@3.55.0 + tslib: 2.4.1 + typescript: 4.8.4 + vite: 4.0.4 + + examples/svelte/simple: + specifiers: + '@sveltejs/vite-plugin-svelte': ^1.0.2 + '@tanstack/svelte-query': ^4.12.0 + '@tsconfig/svelte': ^3.0.0 + svelte: ^3.54.0 + svelte-check: ^2.9.2 + svelte-preprocess: ^4.10.7 + tslib: ^2.4.1 + typescript: ^4.7.4 + vite: ^3.1.0 + dependencies: + '@tanstack/svelte-query': link:../../../packages/svelte-query + devDependencies: + '@sveltejs/vite-plugin-svelte': 1.4.0_svelte@3.55.0+vite@3.2.2 + '@tsconfig/svelte': 3.0.0 + svelte: 3.55.0 + svelte-check: 2.10.3_svelte@3.55.0 + svelte-preprocess: 4.10.7_glsdxddlaertg66rhhvanbinpy + tslib: 2.4.1 + typescript: 4.8.4 + vite: 3.2.2 + + examples/svelte/star-wars: + specifiers: + '@sveltejs/adapter-auto': ^1.0.0 + '@sveltejs/kit': ^1.0.0 + '@tanstack/svelte-query': ^4.12.0 + autoprefixer: ^10.4.13 + postcss: ^8.4.20 + svelte: ^3.54.0 + svelte-check: ^2.9.2 + tailwindcss: ^3.2.4 + tslib: ^2.4.1 + typescript: ^4.7.4 + vite: ^4.0.0 + dependencies: + '@tanstack/svelte-query': link:../../../packages/svelte-query + devDependencies: + '@sveltejs/adapter-auto': 1.0.0_@sveltejs+kit@1.0.7 + '@sveltejs/kit': 1.0.7_svelte@3.55.0+vite@4.0.4 + autoprefixer: 10.4.13_postcss@8.4.21 + postcss: 8.4.21 + svelte: 3.55.0 + svelte-check: 2.10.3_77wbasr76lhjripnylrva3hecy + tailwindcss: 3.2.4_postcss@8.4.21 + tslib: 2.4.1 + typescript: 4.8.4 + vite: 4.0.4 + examples/vue/basic: specifiers: '@tanstack/vue-query': ^4.13.3 @@ -822,6 +1002,41 @@ importers: devDependencies: solid-jest: 0.2.0 + packages/svelte-query: + specifiers: + '@sveltejs/adapter-auto': ^1.0.0 + '@sveltejs/kit': ^1.0.0 + '@sveltejs/package': ^1.0.0 + '@tanstack/query-core': workspace:* + '@testing-library/svelte': ^3.2.2 + '@vitest/coverage-istanbul': ^0.26.3 + eslint-plugin-svelte: ^2.14.1 + jsdom: ^20.0.3 + rimraf: ^3.0.2 + svelte: ^3.54.0 + svelte-check: ^2.9.2 + tslib: ^2.4.1 + typescript: ^4.7.4 + vite: ^4.0.0 + vitest: ^0.26.3 + dependencies: + '@tanstack/query-core': link:../query-core + devDependencies: + '@sveltejs/adapter-auto': 1.0.0_@sveltejs+kit@1.0.7 + '@sveltejs/kit': 1.0.7_svelte@3.55.0+vite@4.0.4 + '@sveltejs/package': 1.0.2_glsdxddlaertg66rhhvanbinpy + '@testing-library/svelte': 3.2.2_svelte@3.55.0 + '@vitest/coverage-istanbul': 0.26.3_jsdom@20.0.3 + eslint-plugin-svelte: 2.14.1_svelte@3.55.0 + jsdom: 20.0.3 + rimraf: 3.0.2 + svelte: 3.55.0 + svelte-check: 2.10.3_svelte@3.55.0 + tslib: 2.4.1 + typescript: 4.8.4 + vite: 4.0.4 + vitest: 0.26.3_jsdom@20.0.3 + packages/vue-query: specifiers: '@tanstack/match-sorter-utils': ^8.1.1 @@ -3990,6 +4205,96 @@ packages: dev: true optional: true + /@esbuild/android-arm/0.16.15: + resolution: {integrity: sha512-JsJtmadyWcR+DEtHLixM7bAQsfi1s0Xotv9kVOoXbCLyhKPOHvMEyh3kJBuTbCPSE4c2jQkQVmarwc9Mg9k3bA==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64/0.16.15: + resolution: {integrity: sha512-OdbkUv7468dSsgoFtHIwTaYAuI5lDEv/v+dlfGBUbVa2xSDIIuSOHXawynw5N9+5lygo/JdXa5/sgGjiEU18gQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64/0.16.15: + resolution: {integrity: sha512-dPUOBiNNWAm+/bxoA75o7R7qqqfcEzXaYlb5uJk2xGHmUMNKSAnDCtRYLgx9/wfE4sXyn8H948OrDyUAHhPOuA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64/0.16.15: + resolution: {integrity: sha512-AksarYV85Hxgwh5/zb6qGl4sYWxIXPQGBAZ+jUro1ZpINy3EWumK+/4DPOKUBPnsrOIvnNXy7Rq4mTeCsMQDNA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64/0.16.15: + resolution: {integrity: sha512-qqrKJxoohceZGGP+sZ5yXkzW9ZiyFZJ1gWSEfuYdOWzBSL18Uy3w7s/IvnDYHo++/cxwqM0ch3HQVReSZy7/4Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64/0.16.15: + resolution: {integrity: sha512-LBWaep6RvJm5KnsKkocdVEzuwnGMjz54fcRVZ9d3R7FSEWOtPBxMhuxeA1n98JVbCLMkTPFmKN6xSnfhnM9WXQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64/0.16.15: + resolution: {integrity: sha512-LE8mKC6JPR04kPLRP9A6k7ZmG0k2aWF4ru79Sde6UeWCo7yDby5f48uJNFQ2pZqzUUkLrHL8xNdIHerJeZjHXg==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm/0.16.15: + resolution: {integrity: sha512-+1sGlqtMJTOnJUXwLUGnDhPaGRKqxT0UONtYacS+EjdDOrSgpQ/1gUXlnze45Z/BogwYaswQM19Gu1YD1T19/w==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64/0.16.15: + resolution: {integrity: sha512-mRYpuQGbzY+XLczy3Sk7fMJ3DRKLGDIuvLKkkUkyecDGQMmil6K/xVKP9IpKO7JtNH477qAiMjjX7jfKae8t4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32/0.16.15: + resolution: {integrity: sha512-puXVFvY4m8EB6/fzu3LdgjiNnEZ3gZMSR7NmKoQe51l3hyQalvTjab3Dt7aX4qGf+8Pj7dsCOBNzNzkSlr/4Aw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64/0.15.9: resolution: {integrity: sha512-O+NfmkfRrb3uSsTa4jE3WApidSe3N5++fyOVGP1SmMZi4A3BZELkhUUvj5hwmMuNdlpzAZ8iAPz2vmcR7DCFQA==} engines: {node: '>=12'} @@ -3999,6 +4304,114 @@ packages: dev: true optional: true + /@esbuild/linux-loong64/0.16.15: + resolution: {integrity: sha512-ATMGb3eg8T6ZTGZFldlGeFEcevBiVq6SBHvRAO04HMfUjZWneZ/U+JJb3YzlNZxuscJ4Tmzq+JrYxlk7ro4dRg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el/0.16.15: + resolution: {integrity: sha512-3SEA4L82OnoSATW+Ve8rPgLaKjC8WMt8fnx7De9kvi/NcVbkj8W+J7qnu/tK2P9pUPQP7Au/0sjPEqZtFeyKQQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64/0.16.15: + resolution: {integrity: sha512-8PgbeX+N6vmqeySzyxO0NyDOltCEW13OS5jUHTvCHmCgf4kNXZtAWJ+zEfJxjRGYhVezQ1FdIm7WfN1R27uOyg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64/0.16.15: + resolution: {integrity: sha512-U+coqH+89vbPVoU30no1Fllrn6gvEeO5tfEArBhjYZ+dQ3Gv7ciQXYf5nrT1QdlIFwEjH4Is1U1iiaGWW+tGpQ==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x/0.16.15: + resolution: {integrity: sha512-M0nKLFMdyFGBoitxG42kq6Xap0CPeDC6gfF9lg7ZejzGF6kqYUGT+pQGl2QCQoxJBeat/LzTma1hG8C3dq2ocg==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64/0.16.15: + resolution: {integrity: sha512-t7/fOXBUKfigvhJLGKZ9TPHHgqNgpIpYaAbcXQk1X+fPeUG7x0tpAbXJ2wST9F/gJ02+CLETPMnhG7Tra2wqsQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64/0.16.15: + resolution: {integrity: sha512-0k0Nxi6DOJmTnLtKD/0rlyqOPpcqONXY53vpkoAsue8CfyhNPWtwzba1ICFNCfCY1dqL3Ho/xEzujJhmdXq1rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64/0.16.15: + resolution: {integrity: sha512-3SkckazfIbdSjsGpuIYT3d6n2Hx0tck3MS1yVsbahhWiLvdy4QozTpvlbjqO3GmvtvhxY4qdyhFOO2wiZKeTAQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64/0.16.15: + resolution: {integrity: sha512-8PNvBC+O8X5EnyIGqE8St2bOjjrXMR17NOLenIrzolvwWnJXvwPo0tE/ahOeiAJmTOS/eAcN8b4LAZcn17Uj7w==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64/0.16.15: + resolution: {integrity: sha512-YPaSgm/mm7kNcATB53OxVGVfn6rDNbImTn330ZlF3hKej1e9ktCaljGjn2vH08z2dlHEf3kdt57tNjE6zs8SzA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32/0.16.15: + resolution: {integrity: sha512-0movUXbSNrTeNf5ZXT0avklEvlJD0hNGZsrrXHfsp9z4tK5xC+apCqmUEZeE9mqrb84Z8XbgGr/MS9LqafTP2A==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64/0.16.15: + resolution: {integrity: sha512-27h5GCcbfomVAqAnMJWvR1LqEY0dFqIq4vTe5nY3becnZNu0SX8F0+gTk3JPvgWQHzaGc6VkPzlOiMkdSUunUA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@eslint/eslintrc/0.4.3: resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==} engines: {node: ^10.12.0 || >=12.0.0} @@ -5227,6 +5640,10 @@ packages: resolution: {integrity: sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q==} dev: false + /@polka/url/1.0.0-next.21: + resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} + dev: true + /@react-native-community/cli-debugger-ui/5.0.1: resolution: {integrity: sha512-5gGKaaXYOVE423BUqxIfvfAVSj5Cg1cU/TpGbeg/iqpy2CfqyWqJB3tTuVUbOOiOvR5wbU8tti6pIi1pchJ+oA==} dependencies: @@ -5562,31 +5979,122 @@ packages: '@sinonjs/commons': 1.8.3 dev: true - /@swc/helpers/0.4.2: - resolution: {integrity: sha512-556Az0VX7WR6UdoTn4htt/l3zPQ7bsQWK+HqdG4swV7beUCxo/BqmvbOpUkTIm/9ih86LIf1qsUnywNL3obGHw==} + /@sveltejs/adapter-auto/1.0.0_@sveltejs+kit@1.0.7: + resolution: {integrity: sha512-yKyPvlLVua1bJ/42FrR3X041mFGdB4GzTZOAEoHUcNBRE5Mhx94+eqHpC3hNvAOiLEDcKfVO0ObyKSu7qldU+w==} + peerDependencies: + '@sveltejs/kit': ^1.0.0 dependencies: - tslib: 2.4.0 - dev: false + '@sveltejs/kit': 1.0.7_svelte@3.55.0+vite@4.0.4 + import-meta-resolve: 2.2.1 + dev: true - /@tanstack/match-sorter-utils/8.1.1: - resolution: {integrity: sha512-IdmEekEYxQsoLOR0XQyw3jD1GujBpRRYaGJYQUw1eOT1eUugWxdc7jomh1VQ1EKHcdwDLpLaCz/8y4KraU4T9A==} - engines: {node: '>=12'} - dependencies: - remove-accents: 0.4.2 - dev: false + /@sveltejs/kit/1.0.7_svelte@3.55.0+vite@4.0.4: + resolution: {integrity: sha512-u8JS4aXFWlrnu/tjl+EhJ/FvBEjLYDyMaLe7EAU4sW+PfDqnqyHBAPg/IQi5JuBg6l+Z816F4WrTe+zplUTQDg==} + engines: {node: ^16.14 || >=18} + hasBin: true + requiresBuild: true + peerDependencies: + svelte: ^3.54.0 + vite: ^4.0.0 + dependencies: + '@sveltejs/vite-plugin-svelte': 2.0.2_svelte@3.55.0+vite@4.0.4 + '@types/cookie': 0.5.1 + cookie: 0.5.0 + devalue: 4.2.0 + esm-env: 1.0.0 + kleur: 4.1.5 + magic-string: 0.27.0 + mime: 3.0.0 + sade: 1.8.1 + set-cookie-parser: 2.5.1 + sirv: 2.0.2 + svelte: 3.55.0 + tiny-glob: 0.2.9 + undici: 5.14.0 + vite: 4.0.4 + transitivePeerDependencies: + - supports-color + dev: true - /@tanstack/match-sorter-utils/8.7.0: - resolution: {integrity: sha512-OgfIPMHTfuw9JGcXCCoEHWFP/eSP2eyhCYwkrFnWBM3NbUPAgOlFP11DbM7cozDRVB0XbPr1tD4pLAtWKlVUVg==} - engines: {node: '>=12'} + /@sveltejs/package/1.0.2_glsdxddlaertg66rhhvanbinpy: + resolution: {integrity: sha512-VY9U+05d9uNFDj7ScKRlHORYlfPSHwJewBjV+V2RsnViexpLFPUrboC9SiPYDCpLnbeqwXerxhO6twGHUBGeIA==} + engines: {node: ^16.14 || >=18} + hasBin: true + peerDependencies: + svelte: ^3.44.0 dependencies: - remove-accents: 0.4.2 - dev: false + chokidar: 3.5.3 + kleur: 4.1.5 + sade: 1.8.1 + svelte: 3.55.0 + svelte2tsx: 0.6.0_glsdxddlaertg66rhhvanbinpy + transitivePeerDependencies: + - typescript + dev: true - /@tanstack/react-location/3.7.4_biqbaboplfbrettd7655fr4n2y: - resolution: {integrity: sha512-6rH2vNHGr0uyeUz5ZHvWMYjeYKGgIKFzvs5749QtnS9f+FU7t7fQE0hKZAzltBZk82LT7iYbcHBRyUg2lW13VA==} - engines: {node: '>=12'} + /@sveltejs/vite-plugin-svelte/1.4.0_svelte@3.55.0+vite@3.2.2: + resolution: {integrity: sha512-6QupI/jemMfK+yI2pMtJcu5iO2gtgTfcBdGwMZZt+lgbFELhszbDl6Qjh000HgAV8+XUA+8EY8DusOFk8WhOIg==} + engines: {node: ^14.18.0 || >= 16} peerDependencies: - react: '>=16' + svelte: ^3.44.0 + vite: ^3.0.0 + dependencies: + debug: 4.3.4 + deepmerge: 4.2.2 + kleur: 4.1.5 + magic-string: 0.26.7 + svelte: 3.55.0 + svelte-hmr: 0.15.1_svelte@3.55.0 + vite: 3.2.2 + vitefu: 0.2.4_vite@3.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@sveltejs/vite-plugin-svelte/2.0.2_svelte@3.55.0+vite@4.0.4: + resolution: {integrity: sha512-xCEan0/NNpQuL0l5aS42FjwQ6wwskdxC3pW1OeFtEKNZwRg7Evro9lac9HesGP6TdFsTv2xMes5ASQVKbCacxg==} + engines: {node: ^14.18.0 || >= 16} + peerDependencies: + svelte: ^3.54.0 + vite: ^4.0.0 + dependencies: + debug: 4.3.4 + deepmerge: 4.2.2 + kleur: 4.1.5 + magic-string: 0.27.0 + svelte: 3.55.0 + svelte-hmr: 0.15.1_svelte@3.55.0 + vite: 4.0.4 + vitefu: 0.2.4_vite@4.0.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@swc/helpers/0.4.2: + resolution: {integrity: sha512-556Az0VX7WR6UdoTn4htt/l3zPQ7bsQWK+HqdG4swV7beUCxo/BqmvbOpUkTIm/9ih86LIf1qsUnywNL3obGHw==} + dependencies: + tslib: 2.4.1 + dev: false + + /@tanstack/match-sorter-utils/8.1.1: + resolution: {integrity: sha512-IdmEekEYxQsoLOR0XQyw3jD1GujBpRRYaGJYQUw1eOT1eUugWxdc7jomh1VQ1EKHcdwDLpLaCz/8y4KraU4T9A==} + engines: {node: '>=12'} + dependencies: + remove-accents: 0.4.2 + dev: false + + /@tanstack/match-sorter-utils/8.7.0: + resolution: {integrity: sha512-OgfIPMHTfuw9JGcXCCoEHWFP/eSP2eyhCYwkrFnWBM3NbUPAgOlFP11DbM7cozDRVB0XbPr1tD4pLAtWKlVUVg==} + engines: {node: '>=12'} + dependencies: + remove-accents: 0.4.2 + dev: false + + /@tanstack/react-location/3.7.4_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-6rH2vNHGr0uyeUz5ZHvWMYjeYKGgIKFzvs5749QtnS9f+FU7t7fQE0hKZAzltBZk82LT7iYbcHBRyUg2lW13VA==} + engines: {node: '>=12'} + peerDependencies: + react: '>=16' react-dom: '>=16' dependencies: '@babel/runtime': 7.18.9 @@ -5702,11 +6210,26 @@ packages: react-dom: 18.2.0_react@18.2.0 dev: true + /@testing-library/svelte/3.2.2_svelte@3.55.0: + resolution: {integrity: sha512-IKwZgqbekC3LpoRhSwhd0JswRGxKdAGkf39UiDXTywK61YyLXbCYoR831e/UUC6EeNW4hiHPY+2WuovxOgI5sw==} + engines: {node: '>= 10'} + peerDependencies: + svelte: 3.x + dependencies: + '@testing-library/dom': 8.18.1 + svelte: 3.55.0 + dev: true + /@tootallnate/once/1.1.2: resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} engines: {node: '>= 6'} dev: true + /@tootallnate/once/2.0.0: + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + dev: true + /@tsconfig/node10/1.0.9: resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} dev: true @@ -5760,10 +6283,24 @@ packages: '@babel/types': 7.19.0 dev: true + /@types/chai-subset/1.3.3: + resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} + dependencies: + '@types/chai': 4.3.4 + dev: true + + /@types/chai/4.3.4: + resolution: {integrity: sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==} + dev: true + /@types/cookie/0.4.1: resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} dev: false + /@types/cookie/0.5.1: + resolution: {integrity: sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==} + dev: true + /@types/estree/0.0.39: resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} dev: true @@ -5842,6 +6379,10 @@ packages: /@types/prop-types/15.7.5: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + /@types/pug/2.0.6: + resolution: {integrity: sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==} + dev: true + /@types/react-dom/17.0.17: resolution: {integrity: sha512-VjnqEmqGnasQKV0CWLevqMTXBYG9GbwuE6x3VetERLh0cq2LTptFE73MrQi2S7GkKXCf2GgwItB/melLnxfnsg==} dependencies: @@ -5893,6 +6434,12 @@ packages: '@types/node': 17.0.45 dev: true + /@types/sass/1.43.1: + resolution: {integrity: sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==} + dependencies: + '@types/node': 17.0.45 + dev: true + /@types/scheduler/0.16.2: resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} @@ -6377,6 +6924,30 @@ packages: vue: 3.2.41 dev: true + /@vitest/coverage-istanbul/0.26.3_jsdom@20.0.3: + resolution: {integrity: sha512-pJRxb+mGy11WdYiam6iW6N4CyhaBbpne+CGPqYGid74SplcR8N07JT3ETDoHKqh5vJCX5UnEIYIreanvFjgLHg==} + dependencies: + istanbul-lib-coverage: 3.2.0 + istanbul-lib-instrument: 5.2.1 + istanbul-lib-report: 3.0.0 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.5 + test-exclude: 6.0.0 + vitest: 0.26.3_jsdom@20.0.3 + transitivePeerDependencies: + - '@edge-runtime/vm' + - '@vitest/browser' + - '@vitest/ui' + - happy-dom + - jsdom + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /@vue/compiler-core/3.2.37: resolution: {integrity: sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==} dependencies: @@ -6439,7 +7010,7 @@ packages: resolution: {integrity: sha512-55Shns6WPxlYsz4WX7q9ZJBL77sKE1ZAYNYStLs6GbhIOMrNtjMvzcob6gu3cGlfpCR4bT7NXgyJ3tly2+Hx8Q==} dependencies: '@babel/parser': 7.19.1 - postcss: 8.4.18 + postcss: 8.4.21 source-map: 0.6.1 dev: true @@ -6454,7 +7025,7 @@ packages: '@vue/shared': 3.2.37 estree-walker: 2.0.2 magic-string: 0.25.9 - postcss: 8.4.18 + postcss: 8.4.21 source-map: 0.6.1 dev: true @@ -6469,7 +7040,7 @@ packages: '@vue/shared': 3.2.39 estree-walker: 2.0.2 magic-string: 0.25.9 - postcss: 8.4.18 + postcss: 8.4.21 source-map: 0.6.1 /@vue/compiler-sfc/3.2.40: @@ -6483,7 +7054,7 @@ packages: '@vue/shared': 3.2.40 estree-walker: 2.0.2 magic-string: 0.25.9 - postcss: 8.4.18 + postcss: 8.4.21 source-map: 0.6.1 /@vue/compiler-sfc/3.2.41: @@ -6497,7 +7068,7 @@ packages: '@vue/shared': 3.2.41 estree-walker: 2.0.2 magic-string: 0.25.9 - postcss: 8.4.18 + postcss: 8.4.21 source-map: 0.6.1 /@vue/compiler-ssr/3.2.37: @@ -6741,6 +7312,13 @@ packages: acorn-walk: 7.2.0 dev: true + /acorn-globals/7.0.1: + resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} + dependencies: + acorn: 8.8.1 + acorn-walk: 8.2.0 + dev: true + /acorn-jsx/5.3.2_acorn@7.4.1: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -6749,12 +7327,20 @@ packages: acorn: 7.4.1 dev: true - /acorn-jsx/5.3.2_acorn@8.8.0: + /acorn-jsx/5.3.2_acorn@8.8.1: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - acorn: 8.8.0 + acorn: 8.8.1 + dev: true + + /acorn-node/1.8.2: + resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==} + dependencies: + acorn: 7.4.1 + acorn-walk: 7.2.0 + xtend: 4.0.2 dev: true /acorn-walk/7.2.0: @@ -6785,6 +7371,12 @@ packages: hasBin: true dev: true + /acorn/8.8.1: + resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + /agent-base/6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -6892,6 +7484,10 @@ packages: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} dev: true + /arg/5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + dev: true + /argparse/1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} dependencies: @@ -7006,6 +7602,10 @@ packages: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} dev: false + /assertion-error/1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: true + /assign-symbols/1.0.0: resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} engines: {node: '>=0.10.0'} @@ -7018,7 +7618,7 @@ packages: resolution: {integrity: sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==} engines: {node: '>=4'} dependencies: - tslib: 2.4.0 + tslib: 2.4.1 /astral-regex/1.0.0: resolution: {integrity: sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==} @@ -7052,6 +7652,22 @@ packages: engines: {node: '>= 4.5.0'} hasBin: true + /autoprefixer/10.4.13_postcss@8.4.21: + resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + dependencies: + browserslist: 4.21.4 + caniuse-lite: 1.0.30001442 + fraction.js: 4.2.0 + normalize-range: 0.1.2 + picocolors: 1.0.0 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + /axe-core/4.4.2: resolution: {integrity: sha512-LVAaGp/wkkgYJcjmHsoKx4juT1aQvJyPcW09MLCjVTh3V2cc6PnyempiLMNH5iMdfIX/zdbjUx2KDjMLCTdPeA==} engines: {node: '>=12'} @@ -7517,7 +8133,7 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001410 + caniuse-lite: 1.0.30001442 electron-to-chromium: 1.4.258 node-releases: 2.0.6 update-browserslist-db: 1.0.9_browserslist@4.21.4 @@ -7545,6 +8161,10 @@ packages: buffer-fill: 1.0.0 dev: false + /buffer-crc32/0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + dev: true + /buffer-equal/0.0.1: resolution: {integrity: sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==} engines: {node: '>=0.4.0'} @@ -7597,6 +8217,13 @@ packages: - debug dev: true + /busboy/1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + dependencies: + streamsearch: 1.1.0 + dev: true + /bytes/3.0.0: resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} engines: {node: '>= 0.8'} @@ -7656,6 +8283,11 @@ packages: engines: {node: '>=6'} dev: true + /camelcase-css/2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + dev: true + /camelcase-keys/6.2.2: resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} engines: {node: '>=8'} @@ -7675,6 +8307,10 @@ packages: /caniuse-lite/1.0.30001410: resolution: {integrity: sha512-QoblBnuE+rG0lc3Ur9ltP5q47lbguipa/ncNMyyGuqPk44FxbScWAeEO+k5fSQ8WekdAK4mWqNs1rADDAiN5xQ==} + dev: false + + /caniuse-lite/1.0.30001442: + resolution: {integrity: sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==} /capture-exit/2.0.0: resolution: {integrity: sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==} @@ -7683,6 +8319,19 @@ packages: rsvp: 4.8.5 dev: false + /chai/4.3.7: + resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.2 + deep-eql: 4.1.3 + get-func-name: 2.0.0 + loupe: 2.3.6 + pathval: 1.1.1 + type-detect: 4.0.8 + dev: true + /chalk/2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -7722,6 +8371,10 @@ packages: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: false + /check-error/1.0.2: + resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} + dev: true + /chokidar/3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -8017,6 +8670,11 @@ packages: engines: {node: '>= 0.6'} dev: false + /cookie/0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + dev: true + /copy-anything/3.0.2: resolution: {integrity: sha512-CzATjGXzUQ0EvuvgOCI6A4BGOo2bcVx8B+eC2nF862iv9fopnPQwlrbACakNCHRIJbCSBj+J/9JeDf60k64MkA==} engines: {node: '>=12.13'} @@ -8134,6 +8792,12 @@ packages: source-map-resolve: 0.6.0 dev: true + /cssesc/3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + /cssom/0.3.8: resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} dev: true @@ -8142,6 +8806,10 @@ packages: resolution: {integrity: sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==} dev: true + /cssom/0.5.0: + resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} + dev: true + /cssstyle/2.3.0: resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} engines: {node: '>=8'} @@ -8181,6 +8849,15 @@ packages: whatwg-url: 8.7.0 dev: true + /data-urls/3.0.2: + resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} + engines: {node: '>=12'} + dependencies: + abab: 2.0.6 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 + dev: true + /date-fns/2.28.0: resolution: {integrity: sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==} engines: {node: '>=0.11'} @@ -8245,18 +8922,29 @@ packages: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} - /decimal.js/10.3.1: - resolution: {integrity: sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==} + /decimal.js/10.4.3: + resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} dev: true /decode-uri-component/0.2.0: resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==} engines: {node: '>=0.10'} + /dedent-js/1.0.1: + resolution: {integrity: sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==} + dev: true + /dedent/0.7.0: resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} dev: true + /deep-eql/4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + dependencies: + type-detect: 4.0.8 + dev: true + /deep-is/0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true @@ -8308,6 +8996,10 @@ packages: is-descriptor: 1.0.2 isobject: 3.0.1 + /defined/1.0.1: + resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==} + dev: true + /delayed-stream/1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -8326,6 +9018,11 @@ packages: engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} dev: false + /detect-indent/6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + dev: true + /detect-newline/3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -8335,6 +9032,24 @@ packages: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} dev: false + /detective/5.2.1: + resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==} + engines: {node: '>=0.8.0'} + hasBin: true + dependencies: + acorn-node: 1.8.2 + defined: 1.0.1 + minimist: 1.2.6 + dev: true + + /devalue/4.2.0: + resolution: {integrity: sha512-mbjoAaCL2qogBKgeFxFPOXAUsZchircF+B/79LD4sHH0+NHfYm8gZpQrskKDn5gENGt35+5OI1GUF7hLVnkPDw==} + dev: true + + /didyoumean/1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + dev: true + /diff-sequences/26.6.2: resolution: {integrity: sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==} engines: {node: '>= 10.14.2'} @@ -8357,6 +9072,10 @@ packages: path-type: 4.0.0 dev: true + /dlv/1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dev: true + /doctrine/2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -8393,6 +9112,13 @@ packages: webidl-conversions: 5.0.0 dev: true + /domexception/4.0.0: + resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} + engines: {node: '>=12'} + dependencies: + webidl-conversions: 7.0.0 + dev: true + /dot-prop/5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} @@ -8473,6 +9199,11 @@ packages: ansi-colors: 4.1.3 dev: true + /entities/4.4.0: + resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} + engines: {node: '>=0.12'} + dev: true + /envinfo/7.8.1: resolution: {integrity: sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==} engines: {node: '>=4'} @@ -8553,6 +9284,10 @@ packages: is-symbol: 1.0.4 dev: true + /es6-promise/3.3.1: + resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} + dev: true + /esbuild-android-64/0.15.9: resolution: {integrity: sha512-HQCX7FJn9T4kxZQkhPjNZC7tBWZqJvhlLHPU2SFzrQB/7nDXjmTIFpFTjt7Bd1uFpeXmuwf5h5fZm+x/hLnhbw==} engines: {node: '>=12'} @@ -8763,6 +9498,36 @@ packages: esbuild-windows-arm64: 0.15.9 dev: true + /esbuild/0.16.15: + resolution: {integrity: sha512-v+3ozjy9wyj8cOElzx3//Lsb4TCxPfZxRmdsfm0YaEkvZu7y6rKH7Zi1UpDx4JI7dSQui+U1Qxhfij9KBbHfrA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.16.15 + '@esbuild/android-arm64': 0.16.15 + '@esbuild/android-x64': 0.16.15 + '@esbuild/darwin-arm64': 0.16.15 + '@esbuild/darwin-x64': 0.16.15 + '@esbuild/freebsd-arm64': 0.16.15 + '@esbuild/freebsd-x64': 0.16.15 + '@esbuild/linux-arm': 0.16.15 + '@esbuild/linux-arm64': 0.16.15 + '@esbuild/linux-ia32': 0.16.15 + '@esbuild/linux-loong64': 0.16.15 + '@esbuild/linux-mips64el': 0.16.15 + '@esbuild/linux-ppc64': 0.16.15 + '@esbuild/linux-riscv64': 0.16.15 + '@esbuild/linux-s390x': 0.16.15 + '@esbuild/linux-x64': 0.16.15 + '@esbuild/netbsd-x64': 0.16.15 + '@esbuild/openbsd-x64': 0.16.15 + '@esbuild/sunos-x64': 0.16.15 + '@esbuild/win32-arm64': 0.16.15 + '@esbuild/win32-ia32': 0.16.15 + '@esbuild/win32-x64': 0.16.15 + dev: true + /escalade/3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -9217,6 +9982,31 @@ packages: eslint: 7.32.0 dev: true + /eslint-plugin-svelte/2.14.1_svelte@3.55.0: + resolution: {integrity: sha512-7M4QHtbtTjLA2xore4rXBwKshPaycil5AsOwYNyvJdunEEdimrIp6otX6PGpFoAojz+qTb4MZuReaHEj1hX7Wg==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0-0 + svelte: ^3.37.0 + peerDependenciesMeta: + svelte: + optional: true + dependencies: + debug: 4.3.4 + eslint-utils: 3.0.0 + esutils: 2.0.3 + known-css-properties: 0.26.0 + postcss: 8.4.21 + postcss-load-config: 3.1.4_postcss@8.4.21 + postcss-safe-parser: 6.0.0_postcss@8.4.21 + sourcemap-codec: 1.4.8 + svelte: 3.55.0 + svelte-eslint-parser: 0.22.3_svelte@3.55.0 + transitivePeerDependencies: + - supports-color + - ts-node + dev: true + /eslint-restricted-globals/0.2.0: resolution: {integrity: sha512-kwYJALm5KS2QW3Mc1PgObO4V+pTR6RQtRT65L1GQILlEnAhabUQqGAX7/qUjoQR4KZJKehWpBtyDEiDecwmY9A==} dev: true @@ -9244,6 +10034,15 @@ packages: eslint-visitor-keys: 1.3.0 dev: true + /eslint-utils/3.0.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint-visitor-keys: 2.1.0 + dev: true + /eslint-utils/3.0.0_eslint@7.32.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} @@ -9376,6 +10175,10 @@ packages: - supports-color dev: true + /esm-env/1.0.0: + resolution: {integrity: sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==} + dev: true + /espree/7.3.1: resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==} engines: {node: ^10.12.0 || >=12.0.0} @@ -9389,8 +10192,8 @@ packages: resolution: {integrity: sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - acorn: 8.8.0 - acorn-jsx: 5.3.2_acorn@8.8.0 + acorn: 8.8.1 + acorn-jsx: 5.3.2_acorn@8.8.1 eslint-visitor-keys: 3.3.0 dev: true @@ -9423,10 +10226,6 @@ packages: engines: {node: '>=4.0'} dev: true - /estree-walker/0.6.1: - resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} - dev: true - /estree-walker/1.0.1: resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} dev: true @@ -9606,7 +10405,7 @@ packages: dependencies: chalk: 4.1.2 commander: 7.2.0 - fast-glob: 3.2.11 + fast-glob: 3.2.12 find-up: 5.0.0 fs-extra: 9.1.0 dev: false @@ -9709,6 +10508,17 @@ packages: glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.5 + dev: true + + /fast-glob/3.2.12: + resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 /fast-json-stable-stringify/2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -9920,6 +10730,19 @@ packages: combined-stream: 1.0.8 mime-types: 2.1.35 + /form-data/4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + + /fraction.js/4.2.0: + resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} + dev: true + /fragment-cache/0.2.1: resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} engines: {node: '>=0.10.0'} @@ -10004,6 +10827,10 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + /get-func-name/2.0.0: + resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} + dev: true + /get-intrinsic/1.1.2: resolution: {integrity: sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==} dependencies: @@ -10116,18 +10943,26 @@ packages: type-fest: 0.20.2 dev: true + /globalyzer/0.1.0: + resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==} + dev: true + /globby/11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.2.11 + fast-glob: 3.2.12 ignore: 5.2.0 merge2: 1.4.1 slash: 3.0.0 dev: true + /globrex/0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + dev: true + /goober/2.1.10: resolution: {integrity: sha512-7PpuQMH10jaTWm33sQgBQvz45pHR8N4l3Cu3WMGEWmHShAcTuuP7I+5/DwKo39fwti5A80WAjvqgz6SSlgWmGA==} peerDependencies: @@ -10315,6 +11150,13 @@ packages: whatwg-encoding: 1.0.5 dev: true + /html-encoding-sniffer/3.0.0: + resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} + engines: {node: '>=12'} + dependencies: + whatwg-encoding: 2.0.0 + dev: true + /html-entities/2.3.2: resolution: {integrity: sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==} dev: true @@ -10345,6 +11187,17 @@ packages: - supports-color dev: true + /http-proxy-agent/5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + dependencies: + '@tootallnate/once': 2.0.0 + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + /https-proxy-agent/5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -10375,7 +11228,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 - dev: false /ieee754/1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -10425,6 +11277,10 @@ packages: resolve-cwd: 3.0.0 dev: true + /import-meta-resolve/2.2.1: + resolution: {integrity: sha512-C6lLL7EJPY44kBvA80gq4uMsVFw5x3oSKfuMl1cuZ2RkI5+UJqQXgn+6hlUew0y4ig7Ypt4CObAAIzU53Nfpuw==} + dev: true + /imurmurhash/0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -10853,6 +11709,19 @@ packages: - supports-color dev: true + /istanbul-lib-instrument/5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.19.1 + '@babel/parser': 7.19.1 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.0 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + /istanbul-lib-report/3.0.0: resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} engines: {node: '>=8'} @@ -10881,6 +11750,14 @@ packages: istanbul-lib-report: 3.0.0 dev: true + /istanbul-reports/3.1.5: + resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.0 + dev: true + /jest-changed-files/27.5.1: resolution: {integrity: sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -11562,12 +12439,12 @@ packages: optional: true dependencies: abab: 2.0.6 - acorn: 8.8.0 + acorn: 8.8.1 acorn-globals: 6.0.0 cssom: 0.4.4 cssstyle: 2.3.0 data-urls: 2.0.0 - decimal.js: 10.3.1 + decimal.js: 10.4.3 domexception: 2.0.1 escodegen: 2.0.0 form-data: 3.0.1 @@ -11575,11 +12452,11 @@ packages: http-proxy-agent: 4.0.1 https-proxy-agent: 5.0.1 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.1 + nwsapi: 2.2.2 parse5: 6.0.1 saxes: 5.0.1 symbol-tree: 3.2.4 - tough-cookie: 4.0.0 + tough-cookie: 4.1.2 w3c-hr-time: 1.0.2 w3c-xmlserializer: 2.0.0 webidl-conversions: 6.1.0 @@ -11594,8 +12471,49 @@ packages: - utf-8-validate dev: true - /jsesc/0.5.0: - resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + /jsdom/20.0.3: + resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} + engines: {node: '>=14'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + dependencies: + abab: 2.0.6 + acorn: 8.8.1 + acorn-globals: 7.0.1 + cssom: 0.5.0 + cssstyle: 2.3.0 + data-urls: 3.0.2 + decimal.js: 10.4.3 + domexception: 4.0.0 + escodegen: 2.0.0 + form-data: 4.0.0 + html-encoding-sniffer: 3.0.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.2 + parse5: 7.1.2 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 4.1.2 + w3c-xmlserializer: 4.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 2.0.0 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 + ws: 8.11.0 + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /jsesc/0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} hasBin: true /jsesc/2.5.2: @@ -11638,6 +12556,10 @@ packages: engines: {node: '>=6'} hasBin: true + /jsonc-parser/3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + dev: true + /jsonfile/2.4.0: resolution: {integrity: sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==} optionalDependencies: @@ -11777,6 +12699,15 @@ packages: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} + /kleur/4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + dev: true + + /known-css-properties/0.26.0: + resolution: {integrity: sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg==} + dev: true + /ky-universal/0.8.2_53xdiffegfcxt6522645rot5ue: resolution: {integrity: sha512-xe0JaOH9QeYxdyGLnzUOVGK4Z6FGvDVzcXFTdrYA1f33MZdEa45sUDaMBy98xQMcsd2XIBrTXRrRYnegcSdgVQ==} engines: {node: '>=10.17'} @@ -11867,6 +12798,11 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true + /local-pkg/0.4.2: + resolution: {integrity: sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==} + engines: {node: '>=14'} + dev: true + /localforage/1.10.0: resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==} dependencies: @@ -11993,6 +12929,18 @@ packages: dependencies: js-tokens: 4.0.0 + /loupe/2.3.6: + resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} + dependencies: + get-func-name: 2.0.0 + dev: true + + /lower-case/2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + dependencies: + tslib: 2.4.1 + dev: true + /lru-cache/4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} dependencies: @@ -12028,6 +12976,20 @@ packages: sourcemap-codec: 1.4.8 dev: true + /magic-string/0.26.7: + resolution: {integrity: sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==} + engines: {node: '>=12'} + dependencies: + sourcemap-codec: 1.4.8 + dev: true + + /magic-string/0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + /make-dir/2.1.0: resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} engines: {node: '>=6'} @@ -12570,6 +13532,12 @@ packages: engines: {node: '>=4.0.0'} hasBin: true + /mime/3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + dev: true + /mimic-fn/1.2.0: resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==} engines: {node: '>=4'} @@ -12632,10 +13600,29 @@ packages: dependencies: minimist: 1.2.6 + /mlly/1.0.0: + resolution: {integrity: sha512-QL108Hwt+u9bXdWgOI0dhzZfACovn5Aen4Xvc8Jasd9ouRH4NjnrXEiyP3nVvJo91zPlYjVRckta0Nt2zfoR6g==} + dependencies: + acorn: 8.8.1 + pathe: 1.0.0 + pkg-types: 1.0.1 + ufo: 1.0.1 + dev: true + /mockdate/3.0.5: resolution: {integrity: sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==} dev: false + /mri/1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + dev: true + + /mrmime/1.0.1: + resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==} + engines: {node: '>=10'} + dev: true + /ms/2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -12769,6 +13756,13 @@ packages: /nice-try/1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + /no-case/3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + dependencies: + lower-case: 2.0.2 + tslib: 2.4.1 + dev: true + /nocache/2.1.0: resolution: {integrity: sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==} engines: {node: '>=4.0.0'} @@ -12862,6 +13856,11 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + /normalize-range/0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + dev: true + /npm-run-path/2.0.2: resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} engines: {node: '>=4'} @@ -12879,8 +13878,8 @@ packages: resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} dev: false - /nwsapi/2.2.1: - resolution: {integrity: sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg==} + /nwsapi/2.2.2: + resolution: {integrity: sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==} dev: true /ob1/0.59.0: @@ -12903,6 +13902,11 @@ packages: define-property: 0.2.5 kind-of: 3.2.2 + /object-hash/3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + dev: true + /object-inspect/1.12.2: resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} dev: true @@ -13231,11 +14235,24 @@ packages: resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} dev: true + /parse5/7.1.2: + resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + dependencies: + entities: 4.4.0 + dev: true + /parseurl/1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} dev: false + /pascal-case/3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + dependencies: + no-case: 3.0.4 + tslib: 2.4.1 + dev: true + /pascalcase/0.1.1: resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} engines: {node: '>=0.10.0'} @@ -13283,6 +14300,18 @@ packages: engines: {node: '>=8'} dev: true + /pathe/0.2.0: + resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==} + dev: true + + /pathe/1.0.0: + resolution: {integrity: sha512-nPdMG0Pd09HuSsr7QOKUXO2Jr9eqaDiZvDwdyIhNG5SHYujkQHYKDfGQkulBxvbDHz8oHLsTgKN86LSwYzSHAg==} + dev: true + + /pathval/1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: true + /performance-now/2.1.0: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} dev: false @@ -13298,6 +14327,11 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + /pify/2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + dev: true + /pify/4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} @@ -13326,6 +14360,14 @@ packages: find-up: 4.1.0 dev: true + /pkg-types/1.0.1: + resolution: {integrity: sha512-jHv9HB+Ho7dj6ItwppRDDl0iZRYBD0jsakHXtFgoLr+cHSF6xC+QL54sJmWxyGxOLYSHm0afhXhXcQDQqH9z8g==} + dependencies: + jsonc-parser: 3.2.0 + mlly: 1.0.0 + pathe: 1.0.0 + dev: true + /pkg-up/3.1.0: resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} engines: {node: '>=8'} @@ -13357,6 +14399,28 @@ packages: resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} engines: {node: '>=0.10.0'} + /postcss-import/14.1.0_postcss@8.4.21: + resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==} + engines: {node: '>=10.0.0'} + peerDependencies: + postcss: ^8.0.0 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.1 + dev: true + + /postcss-js/4.0.0_postcss@8.4.21: + resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.3.3 + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.21 + dev: true + /postcss-load-config/3.1.4: resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} engines: {node: '>= 10'} @@ -13373,6 +14437,54 @@ packages: yaml: 1.10.2 dev: true + /postcss-load-config/3.1.4_postcss@8.4.21: + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 2.0.6 + postcss: 8.4.21 + yaml: 1.10.2 + dev: true + + /postcss-nested/6.0.0_postcss@8.4.21: + resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.11 + dev: true + + /postcss-safe-parser/6.0.0_postcss@8.4.21: + resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.3.3 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-selector-parser/6.0.11: + resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /postcss-value-parser/4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + dev: true + /postcss/8.4.16: resolution: {integrity: sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==} engines: {node: ^10 || ^12 || >=14} @@ -13382,8 +14494,8 @@ packages: source-map-js: 1.0.2 dev: true - /postcss/8.4.18: - resolution: {integrity: sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==} + /postcss/8.4.21: + resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.4 @@ -13525,7 +14637,6 @@ packages: /querystringify/2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - dev: false /queue-microtask/1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -13535,6 +14646,11 @@ packages: engines: {node: '>=8'} dev: true + /quick-lru/5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + dev: true + /raf/3.4.1: resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==} dependencies: @@ -13896,6 +15012,12 @@ packages: dependencies: loose-envify: 1.4.0 + /read-cache/1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + dependencies: + pify: 2.3.0 + dev: true + /read-pkg-up/7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} @@ -13947,7 +15069,7 @@ packages: ast-types: 0.14.2 esprima: 4.0.1 source-map: 0.6.1 - tslib: 2.4.0 + tslib: 2.4.1 /rechoir/0.6.2: resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} @@ -14050,13 +15172,8 @@ packages: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} dev: false - /require-relative/0.8.7: - resolution: {integrity: sha512-AKGr4qvHiryxRb19m3PsLRGuKVAbJLUD7E6eOaHkfKhwc+vSgVOCY5xNvm9EkolBKTOf0GrQAZKLimOCz81Khg==} - dev: true - /requires-port/1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - dev: false /reselect/4.1.6: resolution: {integrity: sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ==} @@ -14143,7 +15260,6 @@ packages: hasBin: true dependencies: glob: 7.2.3 - dev: false /rimraf/3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} @@ -14160,19 +15276,6 @@ packages: - supports-color dev: true - /rollup-plugin-svelte/7.1.0_7rgskvp3hfjz55pue4td2a2xga: - resolution: {integrity: sha512-vopCUq3G+25sKjwF5VilIbiY6KCuMNHP1PFvx2Vr3REBNMDllKHFZN2B9jwwC+MqNc3UPKkjXnceLPEjTjXGXg==} - engines: {node: '>=10'} - peerDependencies: - rollup: '>=2.0.0' - svelte: '>=3.5.0' - dependencies: - require-relative: 0.8.7 - rollup: 2.78.1 - rollup-pluginutils: 2.8.2 - svelte: 3.49.0 - dev: true - /rollup-plugin-terser/7.0.2_rollup@2.78.1: resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} peerDependencies: @@ -14199,12 +15302,6 @@ packages: yargs: 17.5.1 dev: true - /rollup-pluginutils/2.8.2: - resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} - dependencies: - estree-walker: 0.6.1 - dev: true - /rollup/2.78.1: resolution: {integrity: sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==} engines: {node: '>=10.0.0'} @@ -14221,6 +15318,14 @@ packages: fsevents: 2.3.2 dev: true + /rollup/3.9.1: + resolution: {integrity: sha512-GswCYHXftN8ZKGVgQhTFUJB/NBXxrRGgO2NCy6E8s1rwEJ4Q9/VttNqcYfEvx4dTo4j58YqdC3OVztPzlKSX8w==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + /rooks/6.4.3_biqbaboplfbrettd7655fr4n2y: resolution: {integrity: sha512-nHrCdzlU8EAoDo1sNzLLzOSVgqK4ypbhOpLmbsEI7b4xDOagsiePueYwVJizGE4l5qhOYY5x+8YuSYZDp+OMjw==} engines: {node: '>=v10.24.1'} @@ -14252,7 +15357,14 @@ packages: /rxjs/7.5.5: resolution: {integrity: sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==} dependencies: - tslib: 2.4.0 + tslib: 2.4.1 + + /sade/1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + dependencies: + mri: 1.2.0 + dev: true /safe-buffer/5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -14268,6 +15380,15 @@ packages: /safer-buffer/2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + /sander/0.5.1: + resolution: {integrity: sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==} + dependencies: + es6-promise: 3.3.1 + graceful-fs: 4.2.10 + mkdirp: 0.5.6 + rimraf: 2.7.1 + dev: true + /sane/4.1.0: resolution: {integrity: sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==} engines: {node: 6.* || 8.* || >= 10.*} @@ -14297,6 +15418,13 @@ packages: xmlchars: 2.2.0 dev: true + /saxes/6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + dependencies: + xmlchars: 2.2.0 + dev: true + /scheduler/0.20.2: resolution: {integrity: sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==} dependencies: @@ -14392,6 +15520,10 @@ packages: resolution: {integrity: sha512-cHMAtSXilfyBePduZEBVPTCftTQWz6ehWJD5YNUg4mqvRosrrjKbo4WS8JkB0/RxonMoohHm7cOGH60mDkRQ9w==} dev: false + /set-cookie-parser/2.5.1: + resolution: {integrity: sha512-1jeBGaKNGdEq4FgIrORu/N570dwoPYio8lSoYLWmX7sQ//0JY08Xh9o5pBcgmHQ/MbsYp/aZnOe1s1lIsbLprQ==} + dev: true + /set-value/2.0.1: resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} engines: {node: '>=0.10.0'} @@ -14482,6 +15614,15 @@ packages: dependencies: is-arrayish: 0.3.2 + /sirv/2.0.2: + resolution: {integrity: sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w==} + engines: {node: '>= 10'} + dependencies: + '@polka/url': 1.0.0-next.21 + mrmime: 1.0.1 + totalist: 3.0.0 + dev: true + /sisteransi/1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -14610,6 +15751,16 @@ packages: solid-js: 1.5.7 dev: true + /sorcery/0.10.0: + resolution: {integrity: sha512-R5ocFmKZQFfSTstfOtHjJuAwbpGyf9qjQa1egyhvXSbM7emjrtLXtGdZsDJDABC85YBfVvrOiGWKSYXPKdvP1g==} + hasBin: true + dependencies: + buffer-crc32: 0.2.13 + minimist: 1.2.6 + sander: 0.5.1 + sourcemap-codec: 1.4.8 + dev: true + /sort-by/1.2.0: resolution: {integrity: sha512-aRyW65r3xMnf4nxJRluCg0H/woJpksU1dQxRtXYzau30sNBOmf5HACpDd9MZDhKh7ALQ5FgSOfMPwZEtUmMqcg==} dependencies: @@ -14669,6 +15820,7 @@ packages: /sourcemap-codec/1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead /spawn-command/0.0.2-1: resolution: {integrity: sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==} @@ -14778,6 +15930,11 @@ packages: any-promise: 1.3.0 dev: true + /streamsearch/1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + dev: true + /strict-event-emitter/0.2.4: resolution: {integrity: sha512-xIqTLS5azUH1djSUsLH9DbP6UnM/nI18vu8d43JigCQEoVsnY+mrlE+qv6kYqs6/1OkMnMIiL6ffedQSZStuoQ==} dependencies: @@ -14896,6 +16053,12 @@ packages: engines: {node: '>=8'} dev: true + /strip-literal/1.0.0: + resolution: {integrity: sha512-5o4LsH1lzBzO9UFH63AJ2ad2/S2AVx6NtjOcaz+VTT2h1RiRvbipW72z8M/lxEhcPHDBQwpDrnTF7sXy/7OwCQ==} + dependencies: + acorn: 8.8.1 + dev: true + /styled-jsx/5.0.2_react@18.2.0: resolution: {integrity: sha512-LqPQrbBh3egD57NBcHET4qcgshPks+yblyhPlH2GY8oaDgKs8SK4C3dBh3oSJjgzJ3G5t1SYEZGHkP+QEpX9EQ==} engines: {node: '>= 12.0.0'} @@ -14966,11 +16129,203 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /svelte/3.49.0: - resolution: {integrity: sha512-+lmjic1pApJWDfPCpUUTc1m8azDqYCG1JN9YEngrx/hUyIcFJo6VZhj0A1Ai0wqoHcEIuQy+e9tk+4uDgdtsFA==} + /svelte-check/2.10.3_77wbasr76lhjripnylrva3hecy: + resolution: {integrity: sha512-Nt1aWHTOKFReBpmJ1vPug0aGysqPwJh2seM1OvICfM2oeyaA62mOiy5EvkXhltGfhCcIQcq2LoE0l1CwcWPjlw==} + hasBin: true + peerDependencies: + svelte: ^3.24.0 + dependencies: + '@jridgewell/trace-mapping': 0.3.14 + chokidar: 3.5.3 + fast-glob: 3.2.11 + import-fresh: 3.3.0 + picocolors: 1.0.0 + sade: 1.8.1 + svelte: 3.55.0 + svelte-preprocess: 4.10.7_e2sshb7keot2ipsq5ilqqjh4f4 + typescript: 4.8.4 + transitivePeerDependencies: + - '@babel/core' + - coffeescript + - less + - node-sass + - postcss + - postcss-load-config + - pug + - sass + - stylus + - sugarss + dev: true + + /svelte-check/2.10.3_svelte@3.55.0: + resolution: {integrity: sha512-Nt1aWHTOKFReBpmJ1vPug0aGysqPwJh2seM1OvICfM2oeyaA62mOiy5EvkXhltGfhCcIQcq2LoE0l1CwcWPjlw==} + hasBin: true + peerDependencies: + svelte: ^3.24.0 + dependencies: + '@jridgewell/trace-mapping': 0.3.14 + chokidar: 3.5.3 + fast-glob: 3.2.11 + import-fresh: 3.3.0 + picocolors: 1.0.0 + sade: 1.8.1 + svelte: 3.55.0 + svelte-preprocess: 4.10.7_glsdxddlaertg66rhhvanbinpy + typescript: 4.8.4 + transitivePeerDependencies: + - '@babel/core' + - coffeescript + - less + - node-sass + - postcss + - postcss-load-config + - pug + - sass + - stylus + - sugarss + dev: true + + /svelte-eslint-parser/0.22.3_svelte@3.55.0: + resolution: {integrity: sha512-l9M1QbQ8YsF92FNtwHYKoJWnJvBAKB89jmiKLCG9R5GOlidehFzvmxzdK4lsJjzx5UylrTKuKlR815RFopq1Vw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + svelte: ^3.37.0 + dependencies: + eslint-scope: 7.1.1 + eslint-visitor-keys: 3.3.0 + espree: 9.4.0 + svelte: 3.55.0 + dev: true + + /svelte-hmr/0.15.1_svelte@3.55.0: + resolution: {integrity: sha512-BiKB4RZ8YSwRKCNVdNxK/GfY+r4Kjgp9jCLEy0DuqAKfmQtpL38cQK3afdpjw4sqSs4PLi3jIPJIFp259NkZtA==} + engines: {node: ^12.20 || ^14.13.1 || >= 16} + peerDependencies: + svelte: '>=3.19.0' + dependencies: + svelte: 3.55.0 + dev: true + + /svelte-preprocess/4.10.7_e2sshb7keot2ipsq5ilqqjh4f4: + resolution: {integrity: sha512-sNPBnqYD6FnmdBrUmBCaqS00RyCsCpj2BG58A1JBswNF7b0OKviwxqVrOL/CKyJrLSClrSeqQv5BXNg2RUbPOw==} + engines: {node: '>= 9.11.2'} + requiresBuild: true + peerDependencies: + '@babel/core': ^7.10.2 + coffeescript: ^2.5.1 + less: ^3.11.3 || ^4.0.0 + node-sass: '*' + postcss: ^7 || ^8 + postcss-load-config: ^2.1.0 || ^3.0.0 || ^4.0.0 + pug: ^3.0.0 + sass: ^1.26.8 + stylus: ^0.55.0 + sugarss: ^2.0.0 + svelte: ^3.23.0 + typescript: ^3.9.5 || ^4.0.0 + peerDependenciesMeta: + '@babel/core': + optional: true + coffeescript: + optional: true + less: + optional: true + node-sass: + optional: true + postcss: + optional: true + postcss-load-config: + optional: true + pug: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + typescript: + optional: true + dependencies: + '@types/pug': 2.0.6 + '@types/sass': 1.43.1 + detect-indent: 6.1.0 + magic-string: 0.25.9 + postcss: 8.4.21 + sorcery: 0.10.0 + strip-indent: 3.0.0 + svelte: 3.55.0 + typescript: 4.8.4 + dev: true + + /svelte-preprocess/4.10.7_glsdxddlaertg66rhhvanbinpy: + resolution: {integrity: sha512-sNPBnqYD6FnmdBrUmBCaqS00RyCsCpj2BG58A1JBswNF7b0OKviwxqVrOL/CKyJrLSClrSeqQv5BXNg2RUbPOw==} + engines: {node: '>= 9.11.2'} + requiresBuild: true + peerDependencies: + '@babel/core': ^7.10.2 + coffeescript: ^2.5.1 + less: ^3.11.3 || ^4.0.0 + node-sass: '*' + postcss: ^7 || ^8 + postcss-load-config: ^2.1.0 || ^3.0.0 || ^4.0.0 + pug: ^3.0.0 + sass: ^1.26.8 + stylus: ^0.55.0 + sugarss: ^2.0.0 + svelte: ^3.23.0 + typescript: ^3.9.5 || ^4.0.0 + peerDependenciesMeta: + '@babel/core': + optional: true + coffeescript: + optional: true + less: + optional: true + node-sass: + optional: true + postcss: + optional: true + postcss-load-config: + optional: true + pug: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + typescript: + optional: true + dependencies: + '@types/pug': 2.0.6 + '@types/sass': 1.43.1 + detect-indent: 6.1.0 + magic-string: 0.25.9 + sorcery: 0.10.0 + strip-indent: 3.0.0 + svelte: 3.55.0 + typescript: 4.8.4 + dev: true + + /svelte/3.55.0: + resolution: {integrity: sha512-uGu2FVMlOuey4JoKHKrpZFkoYyj0VLjJdz47zX5+gVK5odxHM40RVhar9/iK2YFRVxvfg9FkhfVlR0sjeIrOiA==} engines: {node: '>= 8'} dev: true + /svelte2tsx/0.6.0_glsdxddlaertg66rhhvanbinpy: + resolution: {integrity: sha512-TrxfQkO7CKi8Pu2eC/FyteDCdk3OOeQV5u6z7OjYAsOhsd0ClzAKqxJdvp6xxNQLrbFzf/XvCi9Fy8MQ1MleFA==} + peerDependencies: + svelte: ^3.55 + typescript: ^4.9.4 + dependencies: + dedent-js: 1.0.1 + pascal-case: 3.1.2 + svelte: 3.55.0 + typescript: 4.8.4 + dev: true + /symbol-tree/3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} dev: true @@ -14986,6 +16341,40 @@ packages: strip-ansi: 6.0.1 dev: true + /tailwindcss/3.2.4_postcss@8.4.21: + resolution: {integrity: sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==} + engines: {node: '>=12.13.0'} + hasBin: true + peerDependencies: + postcss: ^8.0.9 + dependencies: + arg: 5.0.2 + chokidar: 3.5.3 + color-name: 1.1.4 + detective: 5.2.1 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.2.12 + glob-parent: 6.0.2 + is-glob: 4.0.3 + lilconfig: 2.0.6 + micromatch: 4.0.5 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.0.0 + postcss: 8.4.21 + postcss-import: 14.1.0_postcss@8.4.21 + postcss-js: 4.0.0_postcss@8.4.21 + postcss-load-config: 3.1.4_postcss@8.4.21 + postcss-nested: 6.0.0_postcss@8.4.21 + postcss-selector-parser: 6.0.11 + postcss-value-parser: 4.2.0 + quick-lru: 5.1.1 + resolve: 1.22.1 + transitivePeerDependencies: + - ts-node + dev: true + /tapable/1.1.3: resolution: {integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==} engines: {node: '>=6'} @@ -15094,6 +16483,13 @@ packages: resolution: {integrity: sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==} dev: true + /tiny-glob/0.2.9: + resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} + dependencies: + globalyzer: 0.1.0 + globrex: 0.1.2 + dev: true + /tiny-invariant/1.2.0: resolution: {integrity: sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==} dev: false @@ -15102,10 +16498,24 @@ packages: resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} dev: false + /tinybench/2.3.1: + resolution: {integrity: sha512-hGYWYBMPr7p4g5IarQE7XhlyWveh1EKhy4wUBS1LrHXCKYgvz+4/jCqgmJqZxxldesn05vccrtME2RLLZNW7iA==} + dev: true + /tinycolor2/1.4.2: resolution: {integrity: sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==} dev: true + /tinypool/0.3.0: + resolution: {integrity: sha512-NX5KeqHOBZU6Bc0xj9Vr5Szbb1j8tUHIeD18s41aDJaPeC5QTdEhK0SpdpUrZlj2nv5cctNcSjaKNanXlfcVEQ==} + engines: {node: '>=14.0.0'} + dev: true + + /tinyspy/1.0.2: + resolution: {integrity: sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==} + engines: {node: '>=14.0.0'} + dev: true + /tmp/0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -15153,13 +16563,19 @@ packages: engines: {node: '>=0.6'} dev: false - /tough-cookie/4.0.0: - resolution: {integrity: sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==} + /totalist/3.0.0: + resolution: {integrity: sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw==} + engines: {node: '>=6'} + dev: true + + /tough-cookie/4.1.2: + resolution: {integrity: sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==} engines: {node: '>=6'} dependencies: psl: 1.9.0 punycode: 2.1.1 - universalify: 0.1.2 + universalify: 0.2.0 + url-parse: 1.5.10 dev: true /tr46/0.0.3: @@ -15178,6 +16594,13 @@ packages: punycode: 2.1.1 dev: true + /tr46/3.0.0: + resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} + engines: {node: '>=12'} + dependencies: + punycode: 2.1.1 + dev: true + /traverse/0.6.6: resolution: {integrity: sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw==} dev: true @@ -15279,8 +16702,8 @@ packages: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} dev: true - /tslib/2.4.0: - resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + /tslib/2.4.1: + resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} /tsup/6.3.0: resolution: {integrity: sha512-IaNQO/o1rFgadLhNonVKNCT2cks+vvnWX3DnL8sB87lBDqRvJXHENr5lSPJlqwplUlDxSwZK8dSg87rgBu6Emw==} @@ -15431,6 +16854,10 @@ packages: resolution: {integrity: sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==} dev: false + /ufo/1.0.1: + resolution: {integrity: sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==} + dev: true + /uglify-es/3.3.9: resolution: {integrity: sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==} engines: {node: '>=0.8.0'} @@ -15454,6 +16881,13 @@ packages: which-boxed-primitive: 1.0.2 dev: true + /undici/5.14.0: + resolution: {integrity: sha512-yJlHYw6yXPPsuOH0x2Ib1Km61vu4hLiRRQoafs+WUgX1vO64vgnxiCEN9dpIrhZyHFsai3F0AEj4P9zy19enEQ==} + engines: {node: '>=12.18'} + dependencies: + busboy: 1.6.0 + dev: true + /unfetch/4.1.0: resolution: {integrity: sha512-crP/n3eAPUJxZXM9T80/yv0YhkTEx2K1D3h7D1AJM6fzsWZrxdyRuLN0JH/dkZh1LNH8LxCnBzoPFCPbb2iGpg==} dev: false @@ -15497,6 +16931,11 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} + /universalify/0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + dev: true + /universalify/1.0.0: resolution: {integrity: sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==} engines: {node: '>= 10.0.0'} @@ -15549,7 +16988,6 @@ packages: dependencies: querystringify: 2.2.0 requires-port: 1.0.0 - dev: false /use-subscription/1.1.1_react@17.0.1: resolution: {integrity: sha512-gk4fPTYvNhs6Ia7u8/+K7bM7sZ7O7AMfWtS+zPO8luH+zWuiGgGcrW0hL4MRWZSzXo+4ofNorf87wZwBKz2YdQ==} @@ -15643,6 +17081,27 @@ packages: engines: {node: '>= 0.8'} dev: false + /vite-node/0.26.3_@types+node@17.0.45: + resolution: {integrity: sha512-Te2bq0Bfvq6XiO718I+1EinMjpNYKws6SNHKOmVbILAQimKoZKDd+IZLlkaYcBXPpK3HFe2U80k8Zw+m3w/a2w==} + engines: {node: '>=v14.16.0'} + hasBin: true + dependencies: + debug: 4.3.4 + mlly: 1.0.0 + pathe: 0.2.0 + source-map: 0.6.1 + source-map-support: 0.5.21 + vite: 4.0.4_@types+node@17.0.45 + transitivePeerDependencies: + - '@types/node' + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vite-plugin-solid/2.3.9_solid-js@1.5.4+vite@3.1.3: resolution: {integrity: sha512-+lprsYgt9DVNp0kbDj2d2HWAPI13L8ff5xslk9SjiPBcsY/YUZ/1Wj0J/Oj5aiVAhwfPm8IcM3bzyHJUPlmc8w==} peerDependencies: @@ -15734,7 +17193,7 @@ packages: optional: true dependencies: esbuild: 0.15.9 - postcss: 8.4.16 + postcss: 8.4.21 resolve: 1.22.1 rollup: 2.78.1 optionalDependencies: @@ -15764,13 +17223,149 @@ packages: optional: true dependencies: esbuild: 0.15.9 - postcss: 8.4.18 + postcss: 8.4.21 resolve: 1.22.1 rollup: 2.79.1 optionalDependencies: fsevents: 2.3.2 dev: true + /vite/4.0.4: + resolution: {integrity: sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.16.15 + postcss: 8.4.21 + resolve: 1.22.1 + rollup: 3.9.1 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vite/4.0.4_@types+node@17.0.45: + resolution: {integrity: sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 17.0.45 + esbuild: 0.16.15 + postcss: 8.4.21 + resolve: 1.22.1 + rollup: 3.9.1 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vitefu/0.2.4_vite@3.2.2: + resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + vite: + optional: true + dependencies: + vite: 3.2.2 + dev: true + + /vitefu/0.2.4_vite@4.0.4: + resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + vite: + optional: true + dependencies: + vite: 4.0.4 + dev: true + + /vitest/0.26.3_jsdom@20.0.3: + resolution: {integrity: sha512-FmHxU9aUCxTi23keF3vxb/Qp0lYXaaJ+jRLGOUmMS3qVTOJvgGE+f1VArupA6pEhaG2Ans4X+zV9dqM5WISMbg==} + engines: {node: '>=v14.16.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/chai': 4.3.4 + '@types/chai-subset': 1.3.3 + '@types/node': 17.0.45 + acorn: 8.8.1 + acorn-walk: 8.2.0 + chai: 4.3.7 + debug: 4.3.4 + jsdom: 20.0.3 + local-pkg: 0.4.2 + source-map: 0.6.1 + strip-literal: 1.0.0 + tinybench: 2.3.1 + tinypool: 0.3.0 + tinyspy: 1.0.2 + vite: 4.0.4_@types+node@17.0.45 + vite-node: 0.26.3_@types+node@17.0.45 + transitivePeerDependencies: + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vlq/1.0.1: resolution: {integrity: sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==} dev: false @@ -15848,6 +17443,13 @@ packages: xml-name-validator: 3.0.0 dev: true + /w3c-xmlserializer/4.0.0: + resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} + engines: {node: '>=14'} + dependencies: + xml-name-validator: 4.0.0 + dev: true + /walker/1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} dependencies: @@ -15885,12 +17487,24 @@ packages: engines: {node: '>=10.4'} dev: true + /webidl-conversions/7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + dev: true + /whatwg-encoding/1.0.5: resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==} dependencies: iconv-lite: 0.4.24 dev: true + /whatwg-encoding/2.0.0: + resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} + engines: {node: '>=12'} + dependencies: + iconv-lite: 0.6.3 + dev: true + /whatwg-fetch/3.0.0: resolution: {integrity: sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==} dev: false @@ -15899,6 +17513,19 @@ packages: resolution: {integrity: sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==} dev: true + /whatwg-mimetype/3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + dev: true + + /whatwg-url/11.0.0: + resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} + engines: {node: '>=12'} + dependencies: + tr46: 3.0.0 + webidl-conversions: 7.0.0 + dev: true + /whatwg-url/5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: @@ -16032,6 +17659,19 @@ packages: utf-8-validate: optional: true + /ws/8.11.0: + resolution: {integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + /xcode/2.1.0: resolution: {integrity: sha512-uCrmPITrqTEzhn0TtT57fJaNaw8YJs1aCzs+P/QqxsDbvPZSv7XMPPwXrKvHtD6pLjBM/NaVwraWJm8q83Y4iQ==} engines: {node: '>=6.0.0'} @@ -16067,6 +17707,11 @@ packages: resolution: {integrity: sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==} dev: true + /xml-name-validator/4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + dev: true + /xml-parse-from-string/1.0.1: resolution: {integrity: sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==} dev: true diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index ecc7b6443e..ff82673364 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,6 +2,7 @@ packages: - 'packages/**' - 'examples/react/**' - 'examples/solid/**' + - 'examples/svelte/**' - 'examples/vue/**' - '!examples/vue/2*' - '!examples/vue/nuxt*' diff --git a/scripts/config.ts b/scripts/config.ts index 830266c069..7156272fdc 100644 --- a/scripts/config.ts +++ b/scripts/config.ts @@ -40,6 +40,11 @@ export const packages: Package[] = [ packageDir: 'solid-query', srcDir: 'src', }, + { + name: '@tanstack/svelte-query', + packageDir: 'svelte-query', + srcDir: 'src', + }, { name: '@tanstack/vue-query', packageDir: 'vue-query', diff --git a/scripts/publish.ts b/scripts/publish.ts index c582d6e240..57d30b1148 100644 --- a/scripts/publish.ts +++ b/scripts/publish.ts @@ -388,6 +388,8 @@ async function run() { const entries = pkg.name === '@tanstack/eslint-plugin-query' ? (['main'] as const) + : pkg.name === '@tanstack/svelte-query' + ? (['types', 'module'] as const) : (['main', 'types', 'module'] as const) await Promise.all( From d79f2b97d226a2a846af51570497ef32ccf53af8 Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Sun, 8 Jan 2023 23:17:23 +1100 Subject: [PATCH 02/37] chore: Remove incompatible vitest flag from test:ci (#4777) * Remove coverage flag Add back again in a simpler script setup * Allow coverage to run on test:ci --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index d9f43318c5..356628920c 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,8 @@ "preinstall": "node -e \"if(process.env.CI == 'true') {console.log('Skipping preinstall...'); process.exit(1)}\" || npx -y only-allow pnpm", "install:csb": "pnpm install --frozen-lockfile", "test": "pnpm run test:ci", - "test:ci": "pnpm run test:format && pnpm run test:eslint && pnpm run test:jest --collectCoverage false && pnpm run typecheck", - "test:react:17": "pnpm --filter \"./packages/react-*\" --no-bail run test:jest --collectCoverage false", + "test:ci": "pnpm run test:format && pnpm run test:eslint && pnpm run test:jest && pnpm run typecheck", + "test:react:17": "pnpm --filter \"./packages/react-*\" --no-bail run test:jest", "test:eslint": "pnpm --filter \"./packages/**\" --no-bail run test:eslint", "test:format": "pnpm run prettier --check", "test:jest": "pnpm --filter \"./packages/**\" --no-bail run test:jest", From 4853ace6e40637a1e850c67efd0cca2241ef7a80 Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Sun, 8 Jan 2023 12:22:20 +0000 Subject: [PATCH 03/37] release: v4.21.0 --- packages/eslint-plugin-query/package.json | 2 +- packages/query-async-storage-persister/package.json | 2 +- packages/query-broadcast-client-experimental/package.json | 2 +- packages/query-core/package.json | 2 +- packages/query-persist-client-core/package.json | 2 +- packages/query-sync-storage-persister/package.json | 2 +- packages/react-query-devtools/package.json | 2 +- packages/react-query-persist-client/package.json | 2 +- packages/react-query/package.json | 2 +- packages/solid-query/package.json | 2 +- packages/svelte-query/package.json | 2 +- packages/vue-query/package.json | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/eslint-plugin-query/package.json b/packages/eslint-plugin-query/package.json index 8f30f0d3cd..6c8436144b 100644 --- a/packages/eslint-plugin-query/package.json +++ b/packages/eslint-plugin-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/eslint-plugin-query", - "version": "4.20.10", + "version": "4.21.0", "description": "ESLint plugin for TanStack Query", "author": "Eliya Cohen", "license": "MIT", diff --git a/packages/query-async-storage-persister/package.json b/packages/query-async-storage-persister/package.json index ad269ab1a1..d45ec03f68 100644 --- a/packages/query-async-storage-persister/package.json +++ b/packages/query-async-storage-persister/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/query-async-storage-persister", - "version": "4.20.9", + "version": "4.21.0", "description": "A persister for asynchronous storages, to be used with TanStack/Query", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/query-broadcast-client-experimental/package.json b/packages/query-broadcast-client-experimental/package.json index 1d23f0bf4d..9f521becf4 100644 --- a/packages/query-broadcast-client-experimental/package.json +++ b/packages/query-broadcast-client-experimental/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/query-broadcast-client-experimental", - "version": "4.20.9", + "version": "4.21.0", "description": "An experimental plugin to for broadcasting the state of your queryClient between browser tabs/windows", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/query-core/package.json b/packages/query-core/package.json index 2bb4730065..8febf61acf 100644 --- a/packages/query-core/package.json +++ b/packages/query-core/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/query-core", - "version": "4.20.9", + "version": "4.21.0", "description": "The framework agnostic core that powers TanStack Query", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/query-persist-client-core/package.json b/packages/query-persist-client-core/package.json index f38dc830b9..fc1d8bebfb 100644 --- a/packages/query-persist-client-core/package.json +++ b/packages/query-persist-client-core/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/query-persist-client-core", - "version": "4.20.9", + "version": "4.21.0", "description": "Set of utilities for interacting with persisters, which can save your queryClient for later use", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/query-sync-storage-persister/package.json b/packages/query-sync-storage-persister/package.json index 7394a3c646..7e19e34806 100644 --- a/packages/query-sync-storage-persister/package.json +++ b/packages/query-sync-storage-persister/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/query-sync-storage-persister", - "version": "4.20.9", + "version": "4.21.0", "description": "A persister for synchronous storages, to be used with TanStack/Query", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/react-query-devtools/package.json b/packages/react-query-devtools/package.json index e1817f1e03..83c6479b6c 100644 --- a/packages/react-query-devtools/package.json +++ b/packages/react-query-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-query-devtools", - "version": "4.20.9", + "version": "4.21.0", "description": "Developer tools to interact with and visualize the TanStack/react-query cache", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/react-query-persist-client/package.json b/packages/react-query-persist-client/package.json index 1037daa875..aad1637ac3 100644 --- a/packages/react-query-persist-client/package.json +++ b/packages/react-query-persist-client/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-query-persist-client", - "version": "4.20.9", + "version": "4.21.0", "description": "React bindings to work with persisters in TanStack/react-query", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/react-query/package.json b/packages/react-query/package.json index 6358993031..ed4d443561 100644 --- a/packages/react-query/package.json +++ b/packages/react-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-query", - "version": "4.20.9", + "version": "4.21.0", "description": "Hooks for managing, caching and syncing asynchronous and remote data in React", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/solid-query/package.json b/packages/solid-query/package.json index 25fd206d8a..56222ab338 100644 --- a/packages/solid-query/package.json +++ b/packages/solid-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/solid-query", - "version": "4.20.9", + "version": "4.21.0", "description": "Primitives for managing, caching and syncing asynchronous and remote data in Solid", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/svelte-query/package.json b/packages/svelte-query/package.json index e1047b82ce..22a902dcc3 100644 --- a/packages/svelte-query/package.json +++ b/packages/svelte-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/svelte-query", - "version": "4.20.0", + "version": "4.21.0", "description": "Primitives for managing, caching and syncing asynchronous and remote data in Svelte", "author": "Dre Johnson", "license": "MIT", diff --git a/packages/vue-query/package.json b/packages/vue-query/package.json index fa0f7addd9..78cae11a3c 100644 --- a/packages/vue-query/package.json +++ b/packages/vue-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/vue-query", - "version": "4.20.9", + "version": "4.21.0", "description": "Hooks for managing, caching and syncing asynchronous and remote data in Vue", "author": "Damian Osipiuk", "license": "MIT", From 228b1f0f2b604047cb52ea5070fa3328b62c176f Mon Sep 17 00:00:00 2001 From: Manthan Mallikarjun Date: Sun, 8 Jan 2023 10:56:12 -0800 Subject: [PATCH 04/37] feat: export default hydration methods for easier extension in `dehydrateOptions` (#4751) * export default hydration metods to allow for easier extending * pretty Co-authored-by: Dominik Dorfmeister --- docs/react/reference/hydration.md | 2 ++ packages/query-core/src/hydration.ts | 4 ++-- packages/query-core/src/index.ts | 7 ++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/react/reference/hydration.md b/docs/react/reference/hydration.md index 7b6b7defe6..76053e057b 100644 --- a/docs/react/reference/hydration.md +++ b/docs/react/reference/hydration.md @@ -33,11 +33,13 @@ const dehydratedState = dehydrate(queryClient, { - This function is called for each mutation in the cache - Return `true` to include this mutation in dehydration, or `false` otherwise - The default version only includes paused mutations + - If you would like to extend the function while retaining the previous behavior, import and execute `defaultShouldDehydrateMutation` as part of the return statement - `shouldDehydrateQuery: (query: Query) => boolean` - Optional - This function is called for each query in the cache - Return `true` to include this query in dehydration, or `false` otherwise - The default version only includes successful queries, do `shouldDehydrateQuery: () => true` to include all queries + - If you would like to extend the function while retaining the previous behavior, import and execute `defaultShouldDehydrateQuery` as part of the return statement **Returns** diff --git a/packages/query-core/src/hydration.ts b/packages/query-core/src/hydration.ts index c44dd64de2..b99f507997 100644 --- a/packages/query-core/src/hydration.ts +++ b/packages/query-core/src/hydration.ts @@ -65,11 +65,11 @@ function dehydrateQuery(query: Query): DehydratedQuery { } } -function defaultShouldDehydrateMutation(mutation: Mutation) { +export function defaultShouldDehydrateMutation(mutation: Mutation) { return mutation.state.isPaused } -function defaultShouldDehydrateQuery(query: Query) { +export function defaultShouldDehydrateQuery(query: Query) { return query.state.status === 'success' } diff --git a/packages/query-core/src/index.ts b/packages/query-core/src/index.ts index 38a3949aa4..15da4a2268 100644 --- a/packages/query-core/src/index.ts +++ b/packages/query-core/src/index.ts @@ -23,7 +23,12 @@ export { } from './utils' export type { MutationFilters, QueryFilters, Updater } from './utils' export { isCancelledError } from './retryer' -export { dehydrate, hydrate } from './hydration' +export { + dehydrate, + hydrate, + defaultShouldDehydrateMutation, + defaultShouldDehydrateQuery, +} from './hydration' // Types export * from './types' From 1a750aff41f18ded49eed22e4889f4b9c1193e3b Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Sun, 8 Jan 2023 19:01:35 +0000 Subject: [PATCH 05/37] release: v4.22.0 --- packages/query-async-storage-persister/package.json | 2 +- packages/query-broadcast-client-experimental/package.json | 2 +- packages/query-core/package.json | 2 +- packages/query-persist-client-core/package.json | 2 +- packages/query-sync-storage-persister/package.json | 2 +- packages/react-query-devtools/package.json | 2 +- packages/react-query-persist-client/package.json | 2 +- packages/react-query/package.json | 2 +- packages/solid-query/package.json | 2 +- packages/svelte-query/package.json | 2 +- packages/vue-query/package.json | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/query-async-storage-persister/package.json b/packages/query-async-storage-persister/package.json index d45ec03f68..57bd5d9fbf 100644 --- a/packages/query-async-storage-persister/package.json +++ b/packages/query-async-storage-persister/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/query-async-storage-persister", - "version": "4.21.0", + "version": "4.22.0", "description": "A persister for asynchronous storages, to be used with TanStack/Query", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/query-broadcast-client-experimental/package.json b/packages/query-broadcast-client-experimental/package.json index 9f521becf4..f1ebdf23ba 100644 --- a/packages/query-broadcast-client-experimental/package.json +++ b/packages/query-broadcast-client-experimental/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/query-broadcast-client-experimental", - "version": "4.21.0", + "version": "4.22.0", "description": "An experimental plugin to for broadcasting the state of your queryClient between browser tabs/windows", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/query-core/package.json b/packages/query-core/package.json index 8febf61acf..4ffb0b25d4 100644 --- a/packages/query-core/package.json +++ b/packages/query-core/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/query-core", - "version": "4.21.0", + "version": "4.22.0", "description": "The framework agnostic core that powers TanStack Query", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/query-persist-client-core/package.json b/packages/query-persist-client-core/package.json index fc1d8bebfb..81de183780 100644 --- a/packages/query-persist-client-core/package.json +++ b/packages/query-persist-client-core/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/query-persist-client-core", - "version": "4.21.0", + "version": "4.22.0", "description": "Set of utilities for interacting with persisters, which can save your queryClient for later use", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/query-sync-storage-persister/package.json b/packages/query-sync-storage-persister/package.json index 7e19e34806..731f17f72c 100644 --- a/packages/query-sync-storage-persister/package.json +++ b/packages/query-sync-storage-persister/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/query-sync-storage-persister", - "version": "4.21.0", + "version": "4.22.0", "description": "A persister for synchronous storages, to be used with TanStack/Query", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/react-query-devtools/package.json b/packages/react-query-devtools/package.json index 83c6479b6c..e5b3dbf5b6 100644 --- a/packages/react-query-devtools/package.json +++ b/packages/react-query-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-query-devtools", - "version": "4.21.0", + "version": "4.22.0", "description": "Developer tools to interact with and visualize the TanStack/react-query cache", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/react-query-persist-client/package.json b/packages/react-query-persist-client/package.json index aad1637ac3..b22b676b65 100644 --- a/packages/react-query-persist-client/package.json +++ b/packages/react-query-persist-client/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-query-persist-client", - "version": "4.21.0", + "version": "4.22.0", "description": "React bindings to work with persisters in TanStack/react-query", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/react-query/package.json b/packages/react-query/package.json index ed4d443561..2327a93365 100644 --- a/packages/react-query/package.json +++ b/packages/react-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-query", - "version": "4.21.0", + "version": "4.22.0", "description": "Hooks for managing, caching and syncing asynchronous and remote data in React", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/solid-query/package.json b/packages/solid-query/package.json index 56222ab338..4f2ee1f7ea 100644 --- a/packages/solid-query/package.json +++ b/packages/solid-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/solid-query", - "version": "4.21.0", + "version": "4.22.0", "description": "Primitives for managing, caching and syncing asynchronous and remote data in Solid", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/svelte-query/package.json b/packages/svelte-query/package.json index 22a902dcc3..54ff3ba3f3 100644 --- a/packages/svelte-query/package.json +++ b/packages/svelte-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/svelte-query", - "version": "4.21.0", + "version": "4.22.0", "description": "Primitives for managing, caching and syncing asynchronous and remote data in Svelte", "author": "Dre Johnson", "license": "MIT", diff --git a/packages/vue-query/package.json b/packages/vue-query/package.json index 78cae11a3c..fce858143e 100644 --- a/packages/vue-query/package.json +++ b/packages/vue-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/vue-query", - "version": "4.21.0", + "version": "4.22.0", "description": "Hooks for managing, caching and syncing asynchronous and remote data in Vue", "author": "Damian Osipiuk", "license": "MIT", From 2e9d2a9b37a4f8b1fe5888b3aa445f677792615f Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Tue, 10 Jan 2023 01:59:48 +1100 Subject: [PATCH 06/37] docs(svelte-query): Add installation and examples (#4781) --- docs/config.json | 41 +++++++++++++++++++++++++++++++++++++ docs/svelte/installation.md | 18 ++++++++++++++++ docs/svelte/overview.md | 10 ++++----- 3 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 docs/svelte/installation.md diff --git a/docs/config.json b/docs/config.json index 86118baba5..76fadc8c50 100644 --- a/docs/config.json +++ b/docs/config.json @@ -690,6 +690,47 @@ { "label": "Overview", "to": "svelte/overview" + }, + { + "label": "Installation", + "to": "svelte/installation" + } + ] + }, + { + "label": "Examples", + "children": [ + { + "label": "Simple", + "to": "svelte/examples/svelte/simple" + }, + { + "label": "Basic", + "to": "svelte/examples/svelte/basic" + }, + { + "label": "Auto Refetching / Polling / Realtime", + "to": "svelte/examples/svelte/auto-refetching" + }, + { + "label": "Optimistic Updates in TypeScript", + "to": "svelte/examples/svelte/optimistic-updates-typescript" + }, + { + "label": "Playground", + "to": "svelte/examples/svelte/playground" + }, + { + "label": "Star Wars", + "to": "svelte/examples/svelte/star-wars" + }, + { + "label": "Infinite Queries", + "to": "svelte/examples/svelte/infinite-loadmore" + }, + { + "label": "Hydration", + "to": "svelte/examples/svelte/hydration" } ] } diff --git a/docs/svelte/installation.md b/docs/svelte/installation.md new file mode 100644 index 0000000000..10e6da1630 --- /dev/null +++ b/docs/svelte/installation.md @@ -0,0 +1,18 @@ +--- +id: installation +title: Installation +--- + +You can install Svelte Query via [NPM](https://npmjs.com). + +### NPM + +```bash +$ npm i @tanstack/svelte-query +# or +$ pnpm add @tanstack/svelte-query +# or +$ yarn add @tanstack/svelte-query +``` + +> Wanna give it a spin before you download? Try out the [basic](/query/v4/docs/svelte/examples/svelte/basic) example! diff --git a/docs/svelte/overview.md b/docs/svelte/overview.md index aeb846850d..671ceb7883 100644 --- a/docs/svelte/overview.md +++ b/docs/svelte/overview.md @@ -12,13 +12,13 @@ Include the QueryClientProvider near the root of your project: ```svelte - + ``` @@ -40,9 +40,9 @@ Then call any function (e.g. createQuery) from any component: {:else if $query.isError}

Error: {$query.error.message}

{:else if $query.isSuccess} - {#each $query.data as todo} -

{todo.title}

- {/each} + {#each $query.data as todo} +

{todo.title}

+ {/each} {/if} ``` From d5126828df75e71991cfef8e9b2d4eb99a5f3593 Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Tue, 10 Jan 2023 18:09:33 +1100 Subject: [PATCH 07/37] chore: Restructure package scripts (#4779) * Use rimraf for clean script Supported on windows * Restructure jest tests, types test, and building types * Relative eslint and jest paths are not needed Now works on windows too, and tested to make sure it doesn't break linux * Run codemod tests from main jest.config.ts --collectCoverage false breaks when passed in to the union of these * Remove unused test:lib scripts * Add prettier-plugin-svelte * Call test:types in github workflow * Add missing build:types to query-async-storage-persister * Simplify build script Co-authored-by: Dominik Dorfmeister --- .github/workflows/pr.yml | 4 ++-- .prettierrc | 5 +++- package.json | 24 +++++++++++-------- packages/eslint-plugin-query/package.json | 13 +++++----- .../package.json | 11 +++++---- .../jest.config.ts | 4 ---- .../package.json | 8 +++---- packages/query-core/package.json | 11 +++++---- .../query-persist-client-core/package.json | 11 +++++---- .../query-sync-storage-persister/package.json | 11 +++++---- packages/react-query-devtools/package.json | 11 +++++---- .../react-query-persist-client/package.json | 11 +++++---- packages/react-query/codemods/jest.config.js | 3 --- packages/react-query/jest.config.ts | 1 + packages/react-query/package.json | 12 ++++++---- packages/solid-query/package.json | 11 +++++---- packages/svelte-query/package.json | 11 +++++---- packages/vue-query/package.json | 11 +++++---- pnpm-lock.yaml | 17 ++++++++++--- 19 files changed, 115 insertions(+), 75 deletions(-) delete mode 100644 packages/query-broadcast-client-experimental/jest.config.ts delete mode 100644 packages/react-query/codemods/jest.config.js diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index a515a076dc..285d101ec5 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -15,7 +15,7 @@ jobs: cache: 'pnpm' - name: Install dependencies run: pnpm --filter "./packages/**" --filter query --prefer-offline install - - run: pnpm run test:jest + - run: pnpm run test:lib - name: Upload coverage to Codecov uses: codecov/codecov-action@v2 lint: @@ -47,7 +47,7 @@ jobs: cache: 'pnpm' - name: Install dependencies run: pnpm --filter "./packages/**" --filter query --prefer-offline install - - run: pnpm run typecheck + - run: pnpm run test:types format: name: 'Format' runs-on: ubuntu-latest diff --git a/.prettierrc b/.prettierrc index e3b414c7e0..dbd332f7cc 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,8 @@ { "semi": false, "singleQuote": true, - "trailingComma": "all" + "trailingComma": "all", + "pluginSearchDirs": false, + "plugins": ["prettier-plugin-svelte"], + "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }] } diff --git a/package.json b/package.json index 356628920c..d6a4bfd820 100644 --- a/package.json +++ b/package.json @@ -2,22 +2,24 @@ "name": "query", "repository": "https://github.com/tanstack/query.git", "scripts": { - "clean": "pnpm --filter \"./packages/**\" --no-bail run clean", + "clean": "pnpm --filter \"./packages/**\" run clean", "preinstall": "node -e \"if(process.env.CI == 'true') {console.log('Skipping preinstall...'); process.exit(1)}\" || npx -y only-allow pnpm", "install:csb": "pnpm install --frozen-lockfile", "test": "pnpm run test:ci", - "test:ci": "pnpm run test:format && pnpm run test:eslint && pnpm run test:jest && pnpm run typecheck", - "test:react:17": "pnpm --filter \"./packages/react-*\" --no-bail run test:jest", - "test:eslint": "pnpm --filter \"./packages/**\" --no-bail run test:eslint", + "test:ci": "pnpm run test:format && pnpm run test:eslint && pnpm run test:lib:publish && pnpm run test:types", + "test:react:17": "pnpm --filter \"./packages/react-*\" run test:lib", + "test:eslint": "pnpm --filter \"./packages/**\" run test:eslint", "test:format": "pnpm run prettier --check", - "test:jest": "pnpm --filter \"./packages/**\" --no-bail run test:jest", + "test:lib": "pnpm --filter \"./packages/**\" run test:lib", + "test:lib:dev": "pnpm --filter \"./packages/**\" run test:lib:dev", + "test:lib:publish": "pnpm --filter \"./packages/**\" run test:lib:publish", "test:size": "pnpm run build && bundlewatch", - "build": "rollup --config rollup.config.js && pnpm run typecheck && pnpm --filter \"@tanstack/eslint-plugin-query\" --filter \"@tanstack/svelte-query\" run build && pnpm run build:copyTypes", - "build:copyTypes": "cp packages/react-query-devtools/build/lib/index.d.ts packages/react-query-devtools/build/lib/index.prod.d.ts", - "typecheck": "tsc -b", - "watch": "concurrently --kill-others \"rollup --config rollup.config.js -w\" \"pnpm run typecheck --watch\"", + "test:types": "pnpm --filter \"./packages/**\" run test:types", + "build": "rollup --config rollup.config.js && pnpm --filter \"./packages/**\" run build && pnpm run build:types", + "build:types": "pnpm --filter \"./packages/**\" run build:types", + "watch": "concurrently --kill-others \"rollup --config rollup.config.js -w\" \"pnpm run build:types --watch\"", "dev": "pnpm run watch", - "prettier": "prettier \"{packages,examples}/**/src/**/*.{md,js,jsx,ts,tsx,json,vue}\"", + "prettier": "prettier --plugin-search-dir . \"{packages,examples}/**/src/**/*.{md,js,jsx,ts,tsx,json,vue,svelte}\"", "prettier:write": "pnpm run prettier --write", "cipublish": "ts-node scripts/publish.ts" }, @@ -73,10 +75,12 @@ "jsonfile": "^6.1.0", "luxon": "^2.3.2", "prettier": "^2.6.2", + "prettier-plugin-svelte": "^2.9.0", "react": "^18.2.0", "react-17": "npm:react@^17.0.2", "react-dom": "^18.2.0", "react-dom-17": "npm:react-dom@^17.0.2", + "rimraf": "^3.0.2", "rollup": "^2.70.2", "rollup-plugin-size": "^0.2.2", "rollup-plugin-terser": "^7.0.2", diff --git a/packages/eslint-plugin-query/package.json b/packages/eslint-plugin-query/package.json index 6c8436144b..5b1b39436f 100644 --- a/packages/eslint-plugin-query/package.json +++ b/packages/eslint-plugin-query/package.json @@ -12,13 +12,14 @@ }, "main": "build/lib/index.js", "scripts": { - "typecheck": "tsc", - "build": "tsup --minify", + "clean": "rimraf ./build", "dev": "tsup --watch --sourcemap", - "clean": "rm -rf ./build", - "test:jest": "../../node_modules/.bin/jest --config ./jest.config.ts", - "test:eslint": "../../node_modules/.bin/eslint --ext .ts,.tsx ./src", - "test:dev": "pnpm run test:jest --watch" + "test:eslint": "eslint --ext .ts,.tsx ./src", + "test:types": "tsc", + "test:lib": "jest --config ./jest.config.ts", + "test:lib:dev": "pnpm run test:lib --watch", + "test:lib:publish": "pnpm run test:lib --collectCoverage false", + "build": "tsup --minify" }, "files": [ "build" diff --git a/packages/query-async-storage-persister/package.json b/packages/query-async-storage-persister/package.json index 57bd5d9fbf..3d73400c9e 100644 --- a/packages/query-async-storage-persister/package.json +++ b/packages/query-async-storage-persister/package.json @@ -28,10 +28,13 @@ "src" ], "scripts": { - "clean": "rm -rf ./build", - "test:eslint": "../../node_modules/.bin/eslint --ext .ts,.tsx ./src", - "test:jest": "../../node_modules/.bin/jest --config ./jest.config.ts", - "test:dev": "pnpm run test:jest --watch" + "clean": "rimraf ./build", + "test:eslint": "eslint --ext .ts,.tsx ./src", + "test:types": "tsc", + "test:lib": "jest --config ./jest.config.ts", + "test:lib:dev": "pnpm run test:lib --watch", + "test:lib:publish": "pnpm run test:lib --collectCoverage false", + "build:types": "tsc --build" }, "dependencies": { "@tanstack/query-persist-client-core": "workspace:*" diff --git a/packages/query-broadcast-client-experimental/jest.config.ts b/packages/query-broadcast-client-experimental/jest.config.ts deleted file mode 100644 index 76da265ace..0000000000 --- a/packages/query-broadcast-client-experimental/jest.config.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default { - displayName: 'query-broadcast-client-experimental', - preset: '../../jest-preset.js', -} diff --git a/packages/query-broadcast-client-experimental/package.json b/packages/query-broadcast-client-experimental/package.json index f1ebdf23ba..bd47efd2aa 100644 --- a/packages/query-broadcast-client-experimental/package.json +++ b/packages/query-broadcast-client-experimental/package.json @@ -28,10 +28,10 @@ "src" ], "scripts": { - "clean": "rm -rf ./build", - "test:eslint": "../../node_modules/.bin/eslint --ext .ts,.tsx ./src", - "test:jest": "../../node_modules/.bin/jest --config ./jest.config.ts --passWithNoTests", - "test:dev": "pnpm run test:jest --watch" + "clean": "rimraf ./build", + "test:eslint": "eslint --ext .ts,.tsx ./src", + "test:types": "tsc", + "build:types": "tsc --build" }, "dependencies": { "@tanstack/query-core": "workspace:*", diff --git a/packages/query-core/package.json b/packages/query-core/package.json index 4ffb0b25d4..2b67a1b785 100644 --- a/packages/query-core/package.json +++ b/packages/query-core/package.json @@ -28,9 +28,12 @@ "src" ], "scripts": { - "clean": "rm -rf ./build", - "test:eslint": "../../node_modules/.bin/eslint --ext .ts,.tsx ./src", - "test:jest": "../../node_modules/.bin/jest --config ./jest.config.ts", - "test:dev": "pnpm run test:jest --watch" + "clean": "rimraf ./build", + "test:eslint": "eslint --ext .ts,.tsx ./src", + "test:types": "tsc", + "test:lib": "jest --config ./jest.config.ts", + "test:lib:dev": "pnpm run test:lib --watch", + "test:lib:publish": "pnpm run test:lib --collectCoverage false", + "build:types": "tsc --build" } } diff --git a/packages/query-persist-client-core/package.json b/packages/query-persist-client-core/package.json index 81de183780..5ed7b5d158 100644 --- a/packages/query-persist-client-core/package.json +++ b/packages/query-persist-client-core/package.json @@ -28,10 +28,13 @@ "src" ], "scripts": { - "clean": "rm -rf ./build", - "test:eslint": "../../node_modules/.bin/eslint --ext .ts,.tsx ./src", - "test:jest": "../../node_modules/.bin/jest --config ./jest.config.ts", - "test:dev": "pnpm run test:jest --watch" + "clean": "rimraf ./build", + "test:eslint": "eslint --ext .ts,.tsx ./src", + "test:types": "tsc", + "test:lib": "jest --config ./jest.config.ts", + "test:lib:dev": "pnpm run test:lib --watch", + "test:lib:publish": "pnpm run test:lib --collectCoverage false", + "build:types": "tsc --build" }, "devDependencies": { "@tanstack/query-core": "workspace:*" diff --git a/packages/query-sync-storage-persister/package.json b/packages/query-sync-storage-persister/package.json index 731f17f72c..be344884c5 100644 --- a/packages/query-sync-storage-persister/package.json +++ b/packages/query-sync-storage-persister/package.json @@ -28,10 +28,13 @@ "src" ], "scripts": { - "clean": "rm -rf ./build", - "test:eslint": "../../node_modules/.bin/eslint --ext .ts,.tsx ./src", - "test:jest": "../../node_modules/.bin/jest --config ./jest.config.ts", - "test:dev": "pnpm run test:jest --watch" + "clean": "rimraf ./build", + "test:eslint": "eslint --ext .ts,.tsx ./src", + "test:types": "tsc", + "test:lib": "jest --config ./jest.config.ts", + "test:lib:dev": "pnpm run test:lib --watch", + "test:lib:publish": "pnpm run test:lib --collectCoverage false", + "build:types": "tsc --build" }, "dependencies": { "@tanstack/query-persist-client-core": "workspace:*" diff --git a/packages/react-query-devtools/package.json b/packages/react-query-devtools/package.json index e5b3dbf5b6..f759ec382c 100644 --- a/packages/react-query-devtools/package.json +++ b/packages/react-query-devtools/package.json @@ -38,10 +38,13 @@ "src" ], "scripts": { - "clean": "rm -rf ./build", - "test:eslint": "../../node_modules/.bin/eslint --ext .ts,.tsx ./src", - "test:jest": "../../node_modules/.bin/jest --config ./jest.config.ts", - "test:dev": "pnpm run test:jest --watch" + "clean": "rimraf ./build", + "test:eslint": "eslint --ext .ts,.tsx ./src", + "test:types": "tsc", + "test:lib": "jest --config ./jest.config.ts", + "test:lib:dev": "pnpm run test:lib --watch", + "test:lib:publish": "pnpm run test:lib --collectCoverage false", + "build:types": "tsc --build && cp build/lib/index.d.ts build/lib/index.prod.d.ts" }, "devDependencies": { "@types/react": "^18.0.14", diff --git a/packages/react-query-persist-client/package.json b/packages/react-query-persist-client/package.json index b22b676b65..bae9ec47e6 100644 --- a/packages/react-query-persist-client/package.json +++ b/packages/react-query-persist-client/package.json @@ -28,10 +28,13 @@ "src" ], "scripts": { - "clean": "rm -rf ./build", - "test:eslint": "../../node_modules/.bin/eslint --ext .ts,.tsx ./src", - "test:jest": "../../node_modules/.bin/jest --config ./jest.config.ts", - "test:dev": "pnpm run test:jest --watch" + "clean": "rimraf ./build", + "test:eslint": "eslint --ext .ts,.tsx ./src", + "test:types": "tsc", + "test:lib": "jest --config ./jest.config.ts", + "test:lib:dev": "pnpm run test:lib --watch", + "test:lib:publish": "pnpm run test:lib --collectCoverage false", + "build:types": "tsc --build" }, "devDependencies": { "@types/react": "^18.0.14", diff --git a/packages/react-query/codemods/jest.config.js b/packages/react-query/codemods/jest.config.js deleted file mode 100644 index 5b36187188..0000000000 --- a/packages/react-query/codemods/jest.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - testMatch: ['/**/*.test.js'], -} diff --git a/packages/react-query/jest.config.ts b/packages/react-query/jest.config.ts index fbe2267f71..f4a5b3fedd 100644 --- a/packages/react-query/jest.config.ts +++ b/packages/react-query/jest.config.ts @@ -2,4 +2,5 @@ export default { displayName: 'react-query', preset: '../../jest-preset.js', setupFilesAfterEnv: ['./jest.setup.ts'], + testMatch: ['/src/**/*.test.tsx', '/codemods/**/*.test.js'], } diff --git a/packages/react-query/package.json b/packages/react-query/package.json index 2327a93365..1800d9d897 100644 --- a/packages/react-query/package.json +++ b/packages/react-query/package.json @@ -25,11 +25,13 @@ "./src/setBatchUpdatesFn.ts" ], "scripts": { - "clean": "rm -rf ./build", - "test:codemods": "../../node_modules/.bin/jest --config codemods/jest.config.js", - "test:eslint": "../../node_modules/.bin/eslint --ext .ts,.tsx ./src", - "test:jest": "pnpm run test:codemods && ../../node_modules/.bin/jest --config ./jest.config.ts", - "test:dev": "pnpm run test:jest --watch" + "clean": "rimraf ./build", + "test:eslint": "eslint --ext .ts,.tsx ./src", + "test:types": "tsc", + "test:lib": "jest --config ./jest.config.ts", + "test:lib:dev": "pnpm run test:lib --watch", + "test:lib:publish": "pnpm run test:lib --collectCoverage false", + "build:types": "tsc --build" }, "files": [ "build/lib/*", diff --git a/packages/solid-query/package.json b/packages/solid-query/package.json index 4f2ee1f7ea..29f1a5178e 100644 --- a/packages/solid-query/package.json +++ b/packages/solid-query/package.json @@ -27,10 +27,13 @@ }, "sideEffects": false, "scripts": { - "clean": "rm -rf ./build", - "test:eslint": "../../node_modules/.bin/eslint --ext .ts,.tsx ./src", - "test:jest": "../../node_modules/.bin/jest --config ./jest.config.ts", - "test:dev": "pnpm run test:jest --watch" + "clean": "rimraf ./build", + "test:eslint": "eslint --ext .ts,.tsx ./src", + "test:types": "tsc", + "test:lib": "jest --config ./jest.config.ts", + "test:lib:dev": "pnpm run test:lib --watch", + "test:lib:publish": "pnpm run test:lib --collectCoverage false", + "build:types": "tsc --build" }, "files": [ "build/lib/*", diff --git a/packages/svelte-query/package.json b/packages/svelte-query/package.json index 54ff3ba3f3..36d927ab31 100644 --- a/packages/svelte-query/package.json +++ b/packages/svelte-query/package.json @@ -15,10 +15,12 @@ "type": "module", "scripts": { "clean": "rimraf ./build", - "build": "svelte-kit sync && svelte-package && rimraf ./build/lib/package.json", - "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", - "test:eslint": "svelte-kit sync && ../../node_modules/.bin/eslint --ext .svelte,.ts ./src", - "test:jest": "svelte-kit sync && vitest run --coverage" + "test:types": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "test:eslint": "svelte-kit sync && eslint --ext .svelte,.ts ./src", + "test:lib": "svelte-kit sync && vitest run --coverage true", + "test:lib:dev": "svelte-kit sync && vitest watch", + "test:lib:publish": "svelte-kit sync && vitest run --coverage false", + "build": "svelte-kit sync && svelte-package && rimraf ./build/lib/package.json" }, "devDependencies": { "@sveltejs/adapter-auto": "^1.0.0", @@ -28,7 +30,6 @@ "@vitest/coverage-istanbul": "^0.26.3", "eslint-plugin-svelte": "^2.14.1", "jsdom": "^20.0.3", - "rimraf": "^3.0.2", "svelte": "^3.54.0", "svelte-check": "^2.9.2", "tslib": "^2.4.1", diff --git a/packages/vue-query/package.json b/packages/vue-query/package.json index fce858143e..15fb0f41e4 100644 --- a/packages/vue-query/package.json +++ b/packages/vue-query/package.json @@ -27,10 +27,13 @@ }, "sideEffects": false, "scripts": { - "clean": "rm -rf ./build", - "test:eslint": "../../node_modules/.bin/eslint --ext .ts ./src", - "test:jest": "../../node_modules/.bin/jest --config ./jest.config.ts", - "test:dev": "pnpm run test:jest --watch" + "clean": "rimraf ./build", + "test:eslint": "eslint --ext .ts ./src", + "test:types": "tsc", + "test:lib": "jest --config ./jest.config.ts", + "test:lib:dev": "pnpm run test:lib --watch", + "test:lib:publish": "pnpm run test:lib --collectCoverage false", + "build:types": "tsc --build" }, "files": [ "build/lib/*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bd351508ef..454403ed3b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -54,10 +54,12 @@ importers: jsonfile: ^6.1.0 luxon: ^2.3.2 prettier: ^2.6.2 + prettier-plugin-svelte: ^2.9.0 react: ^18.2.0 react-17: npm:react@^17.0.2 react-dom: ^18.2.0 react-dom-17: npm:react-dom@^17.0.2 + rimraf: ^3.0.2 rollup: ^2.70.2 rollup-plugin-size: ^0.2.2 rollup-plugin-terser: ^7.0.2 @@ -120,10 +122,12 @@ importers: jsonfile: 6.1.0 luxon: 2.4.0 prettier: 2.7.1 + prettier-plugin-svelte: 2.9.0_prettier@2.7.1 react: 18.2.0 react-17: /react/17.0.2 react-dom: 18.2.0_react@18.2.0 react-dom-17: /react-dom/17.0.2_react@18.2.0 + rimraf: 3.0.2 rollup: 2.78.1 rollup-plugin-size: 0.2.2 rollup-plugin-terser: 7.0.2_rollup@2.78.1 @@ -1012,7 +1016,6 @@ importers: '@vitest/coverage-istanbul': ^0.26.3 eslint-plugin-svelte: ^2.14.1 jsdom: ^20.0.3 - rimraf: ^3.0.2 svelte: ^3.54.0 svelte-check: ^2.9.2 tslib: ^2.4.1 @@ -1029,7 +1032,6 @@ importers: '@vitest/coverage-istanbul': 0.26.3_jsdom@20.0.3 eslint-plugin-svelte: 2.14.1_svelte@3.55.0 jsdom: 20.0.3 - rimraf: 3.0.2 svelte: 3.55.0 svelte-check: 2.10.3_svelte@3.55.0 tslib: 2.4.1 @@ -14528,6 +14530,15 @@ packages: fast-diff: 1.2.0 dev: true + /prettier-plugin-svelte/2.9.0_prettier@2.7.1: + resolution: {integrity: sha512-3doBi5NO4IVgaNPtwewvrgPpqAcvNv0NwJNflr76PIGgi9nf1oguQV1Hpdm9TI2ALIQVn/9iIwLpBO5UcD2Jiw==} + peerDependencies: + prettier: ^1.16.4 || ^2.0.0 + svelte: ^3.2.0 + dependencies: + prettier: 2.7.1 + dev: true + /prettier/2.7.1: resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==} engines: {node: '>=10.13.0'} @@ -14725,7 +14736,7 @@ packages: peerDependencies: react: '>=16.13.1' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.19.0 react: 18.2.0 dev: true From c21095798c9876e408c4f955b9794a23e00e39b0 Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Tue, 10 Jan 2023 19:20:54 +1100 Subject: [PATCH 08/37] docs(svelte-query): Add SSR and SvelteKit guide (#4786) * Add SSR docs * Remove semicolons to match project style --- docs/config.json | 4 ++ docs/svelte/overview.md | 6 +-- docs/svelte/ssr.md | 110 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 docs/svelte/ssr.md diff --git a/docs/config.json b/docs/config.json index 76fadc8c50..207cb864b3 100644 --- a/docs/config.json +++ b/docs/config.json @@ -694,6 +694,10 @@ { "label": "Installation", "to": "svelte/installation" + }, + { + "label": "SSR & SvelteKit", + "to": "react/guides/ssr" } ] }, diff --git a/docs/svelte/overview.md b/docs/svelte/overview.md index 671ceb7883..54676713e3 100644 --- a/docs/svelte/overview.md +++ b/docs/svelte/overview.md @@ -1,6 +1,6 @@ --- id: overview -title: Svelte Query +title: Overview --- The `@tanstack/svelte-query` package offers a 1st-class API for using TanStack Query via Svelte. @@ -9,7 +9,7 @@ The `@tanstack/svelte-query` package offers a 1st-class API for using TanStack Q Include the QueryClientProvider near the root of your project: -```svelte +```markdown +``` + +Pros: + +- This setup is minimal and this can be a quick solution for some cases + +Cons: + +- If you are calling `createQuery` in a component deeper down in the tree you need to pass the `initialData` down to that point +- If you are calling `createQuery` with the same query in multiple locations, you need to pass `initialData` to all of them +- There is no way to know at what time the query was fetched on the server, so `dataUpdatedAt` and determining if the query needs refetching is based on when the page loaded instead + +## Using `prefetchQuery` + +Svelte Query supports prefetching queries on the server. Using this setup below, you can fetch data and pass it into QueryClientProvider before it is sent to the user's browser. Therefore, this data is already available in the cache, and no initial fetch occurs client-side. + +**src/routes/+layout.ts** +```ts +import { QueryClient } from '@tanstack/svelte-query' +import type { LayoutLoad } from './$types' + +export const load: LayoutLoad = async () => { + const queryClient = new QueryClient() + return { queryClient } +} +``` + +**src/routes/+layout.svelte** +```markdown + + + + + +``` + +**src/routes/+page.ts** +```ts +import type { PageLoad } from './$types' + +export const load: PageLoad = async ({ parent }) => { + const { queryClient } = await parent() + await queryClient.prefetchQuery({ + queryKey: ['posts'], + queryFn: getPosts + }) +} +``` + +**src/routes/+page.svelte** +```markdown + +``` + +Pros: + +- Server-loaded data can be accessed anywhere without prop-drilling +- No initial fetch occurs client-side once the page is rendered, as the query cache retains all information about the query was made including `dataUpdatedAt` + +Cons: + +- Requires more files for initial setup From b40055c67275ef01c9ae1bebbbb3875f589c4049 Mon Sep 17 00:00:00 2001 From: ottomated <31470743+ottomated@users.noreply.github.com> Date: Wed, 11 Jan 2023 00:52:11 -0800 Subject: [PATCH 09/37] docs: fix sveltekit SSR link (#4792) --- docs/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config.json b/docs/config.json index 207cb864b3..b4e86184e8 100644 --- a/docs/config.json +++ b/docs/config.json @@ -697,7 +697,7 @@ }, { "label": "SSR & SvelteKit", - "to": "react/guides/ssr" + "to": "svelte/ssr" } ] }, From 84ba2f18549f1ce1fd77d86b8e95d00fc2a4d0bd Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Wed, 11 Jan 2023 21:42:58 +1100 Subject: [PATCH 10/37] fix(svelte-query): Remove dependency on SvelteKit (#4788) * Use rimraf for clean script Supported on windows * Restructure jest tests, types test, and building types * Relative eslint and jest paths are not needed Now works on windows too, and tested to make sure it doesn't break linux * Run codemod tests from main jest.config.ts --collectCoverage false breaks when passed in to the union of these * Remove unused test:lib scripts * Add prettier-plugin-svelte * Call test:types in github workflow * Add missing build:types to query-async-storage-persister * Build without sveltekit * Update vite-plugin-svelte to 2.0 * Add dev/watch script to svelte-query * Replace sveltePreprocess with vitePreprocess * Fix example component and indentation * Remove dev/watch Breaks setup because it adds package.json that isn't removed by rimraf * Move /src/lib to /src, ignore __tests__ in build * Fix tsconfig included files * Replace tabs with spaces * Whoops messed up merge * Add more tsconfig.json settings Co-authored-by: Dominik Dorfmeister --- examples/svelte/auto-refetching/package.json | 1 - .../svelte/auto-refetching/svelte.config.js | 4 +- examples/svelte/basic/package.json | 5 +- examples/svelte/basic/svelte.config.js | 4 +- examples/svelte/hydration/package.json | 1 - examples/svelte/hydration/svelte.config.js | 4 +- .../svelte/infinite-loadmore/package.json | 5 +- .../svelte/infinite-loadmore/svelte.config.js | 4 +- .../package.json | 1 - .../svelte.config.js | 4 +- examples/svelte/simple/package.json | 5 +- examples/svelte/simple/svelte.config.js | 4 +- packages/svelte-query/package.json | 15 ++-- .../svelte-query/src/{lib => }/Hydrate.svelte | 0 .../src/{lib => }/QueryClientProvider.svelte | 0 .../src/__tests__/CreateMutation.svelte | 4 +- .../src/__tests__/CreateQuery.svelte | 4 +- packages/svelte-query/src/__tests__/utils.ts | 2 +- .../svelte-query/src/{lib => }/context.ts | 0 .../src/{lib => }/createBaseQuery.ts | 0 .../src/{lib => }/createInfiniteQuery.ts | 0 .../src/{lib => }/createMutation.ts | 0 .../src/{lib => }/createQueries.ts | 0 .../svelte-query/src/{lib => }/createQuery.ts | 0 packages/svelte-query/src/{lib => }/index.ts | 0 packages/svelte-query/src/{lib => }/types.ts | 0 .../svelte-query/src/{lib => }/useHydrate.ts | 0 .../src/{lib => }/useIsFetching.ts | 0 .../src/{lib => }/useIsMutating.ts | 0 .../src/{lib => }/useQueryClient.ts | 0 packages/svelte-query/svelte.config.js | 16 ++-- packages/svelte-query/tsconfig.json | 27 ++++++- packages/svelte-query/vite.config.ts | 4 +- pnpm-lock.yaml | 79 ++++--------------- 34 files changed, 77 insertions(+), 116 deletions(-) rename packages/svelte-query/src/{lib => }/Hydrate.svelte (100%) rename packages/svelte-query/src/{lib => }/QueryClientProvider.svelte (100%) rename packages/svelte-query/src/{lib => }/context.ts (100%) rename packages/svelte-query/src/{lib => }/createBaseQuery.ts (100%) rename packages/svelte-query/src/{lib => }/createInfiniteQuery.ts (100%) rename packages/svelte-query/src/{lib => }/createMutation.ts (100%) rename packages/svelte-query/src/{lib => }/createQueries.ts (100%) rename packages/svelte-query/src/{lib => }/createQuery.ts (100%) rename packages/svelte-query/src/{lib => }/index.ts (100%) rename packages/svelte-query/src/{lib => }/types.ts (100%) rename packages/svelte-query/src/{lib => }/useHydrate.ts (100%) rename packages/svelte-query/src/{lib => }/useIsFetching.ts (100%) rename packages/svelte-query/src/{lib => }/useIsMutating.ts (100%) rename packages/svelte-query/src/{lib => }/useQueryClient.ts (100%) diff --git a/examples/svelte/auto-refetching/package.json b/examples/svelte/auto-refetching/package.json index d6432d57d7..43e4813e21 100644 --- a/examples/svelte/auto-refetching/package.json +++ b/examples/svelte/auto-refetching/package.json @@ -16,7 +16,6 @@ "@sveltejs/kit": "^1.0.0", "svelte": "^3.54.0", "svelte-check": "^2.9.2", - "svelte-preprocess": "^4.10.7", "tslib": "^2.4.1", "typescript": "^4.7.4", "vite": "^4.0.0" diff --git a/examples/svelte/auto-refetching/svelte.config.js b/examples/svelte/auto-refetching/svelte.config.js index 23f07d2032..836e30422d 100644 --- a/examples/svelte/auto-refetching/svelte.config.js +++ b/examples/svelte/auto-refetching/svelte.config.js @@ -1,11 +1,11 @@ import adapter from '@sveltejs/adapter-auto'; -import preprocess from 'svelte-preprocess'; +import { vitePreprocess } from '@sveltejs/kit/vite'; /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://github.com/sveltejs/svelte-preprocess // for more information about preprocessors - preprocess: preprocess(), + preprocess: vitePreprocess(), kit: { adapter: adapter() diff --git a/examples/svelte/basic/package.json b/examples/svelte/basic/package.json index b25206615b..e109a9256e 100644 --- a/examples/svelte/basic/package.json +++ b/examples/svelte/basic/package.json @@ -13,13 +13,12 @@ "@tanstack/svelte-query": "^4.12.0" }, "devDependencies": { - "@sveltejs/vite-plugin-svelte": "^1.0.2", + "@sveltejs/vite-plugin-svelte": "^2.0.2", "@tsconfig/svelte": "^3.0.0", "svelte": "^3.54.0", "svelte-check": "^2.9.2", - "svelte-preprocess": "^4.10.7", "tslib": "^2.4.1", "typescript": "^4.7.4", - "vite": "^3.1.0" + "vite": "^4.0.0" } } diff --git a/examples/svelte/basic/svelte.config.js b/examples/svelte/basic/svelte.config.js index 3630bb3963..49c64ac5bf 100644 --- a/examples/svelte/basic/svelte.config.js +++ b/examples/svelte/basic/svelte.config.js @@ -1,7 +1,7 @@ -import sveltePreprocess from 'svelte-preprocess' +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' export default { // Consult https://github.com/sveltejs/svelte-preprocess // for more information about preprocessors - preprocess: sveltePreprocess() + preprocess: vitePreprocess() } diff --git a/examples/svelte/hydration/package.json b/examples/svelte/hydration/package.json index 4fd347a946..9003457846 100644 --- a/examples/svelte/hydration/package.json +++ b/examples/svelte/hydration/package.json @@ -16,7 +16,6 @@ "@sveltejs/kit": "^1.0.0", "svelte": "^3.54.0", "svelte-check": "^2.9.2", - "svelte-preprocess": "^4.10.7", "tslib": "^2.4.1", "typescript": "^4.7.4", "vite": "^4.0.0" diff --git a/examples/svelte/hydration/svelte.config.js b/examples/svelte/hydration/svelte.config.js index 23f07d2032..836e30422d 100644 --- a/examples/svelte/hydration/svelte.config.js +++ b/examples/svelte/hydration/svelte.config.js @@ -1,11 +1,11 @@ import adapter from '@sveltejs/adapter-auto'; -import preprocess from 'svelte-preprocess'; +import { vitePreprocess } from '@sveltejs/kit/vite'; /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://github.com/sveltejs/svelte-preprocess // for more information about preprocessors - preprocess: preprocess(), + preprocess: vitePreprocess(), kit: { adapter: adapter() diff --git a/examples/svelte/infinite-loadmore/package.json b/examples/svelte/infinite-loadmore/package.json index 3c05d84c76..ef04ab2da0 100644 --- a/examples/svelte/infinite-loadmore/package.json +++ b/examples/svelte/infinite-loadmore/package.json @@ -13,13 +13,12 @@ "@tanstack/svelte-query": "^4.12.0" }, "devDependencies": { - "@sveltejs/vite-plugin-svelte": "^1.0.2", + "@sveltejs/vite-plugin-svelte": "^2.0.2", "@tsconfig/svelte": "^3.0.0", "svelte": "^3.54.0", "svelte-check": "^2.9.2", - "svelte-preprocess": "^4.10.7", "tslib": "^2.4.1", "typescript": "^4.7.4", - "vite": "^3.1.0" + "vite": "^4.0.0" } } diff --git a/examples/svelte/infinite-loadmore/svelte.config.js b/examples/svelte/infinite-loadmore/svelte.config.js index 3630bb3963..49c64ac5bf 100644 --- a/examples/svelte/infinite-loadmore/svelte.config.js +++ b/examples/svelte/infinite-loadmore/svelte.config.js @@ -1,7 +1,7 @@ -import sveltePreprocess from 'svelte-preprocess' +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' export default { // Consult https://github.com/sveltejs/svelte-preprocess // for more information about preprocessors - preprocess: sveltePreprocess() + preprocess: vitePreprocess() } diff --git a/examples/svelte/optimistic-updates-typescript/package.json b/examples/svelte/optimistic-updates-typescript/package.json index ecb0a68baf..85c895df82 100644 --- a/examples/svelte/optimistic-updates-typescript/package.json +++ b/examples/svelte/optimistic-updates-typescript/package.json @@ -16,7 +16,6 @@ "@sveltejs/kit": "^1.0.0", "svelte": "^3.54.0", "svelte-check": "^2.9.2", - "svelte-preprocess": "^4.10.7", "tslib": "^2.4.1", "typescript": "^4.7.4", "vite": "^4.0.0" diff --git a/examples/svelte/optimistic-updates-typescript/svelte.config.js b/examples/svelte/optimistic-updates-typescript/svelte.config.js index 23f07d2032..836e30422d 100644 --- a/examples/svelte/optimistic-updates-typescript/svelte.config.js +++ b/examples/svelte/optimistic-updates-typescript/svelte.config.js @@ -1,11 +1,11 @@ import adapter from '@sveltejs/adapter-auto'; -import preprocess from 'svelte-preprocess'; +import { vitePreprocess } from '@sveltejs/kit/vite'; /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://github.com/sveltejs/svelte-preprocess // for more information about preprocessors - preprocess: preprocess(), + preprocess: vitePreprocess(), kit: { adapter: adapter() diff --git a/examples/svelte/simple/package.json b/examples/svelte/simple/package.json index a9443f784e..19d0ac364f 100644 --- a/examples/svelte/simple/package.json +++ b/examples/svelte/simple/package.json @@ -13,13 +13,12 @@ "@tanstack/svelte-query": "^4.12.0" }, "devDependencies": { - "@sveltejs/vite-plugin-svelte": "^1.0.2", + "@sveltejs/vite-plugin-svelte": "^2.0.2", "@tsconfig/svelte": "^3.0.0", "svelte": "^3.54.0", "svelte-check": "^2.9.2", - "svelte-preprocess": "^4.10.7", "tslib": "^2.4.1", "typescript": "^4.7.4", - "vite": "^3.1.0" + "vite": "^4.0.0" } } diff --git a/examples/svelte/simple/svelte.config.js b/examples/svelte/simple/svelte.config.js index 3630bb3963..49c64ac5bf 100644 --- a/examples/svelte/simple/svelte.config.js +++ b/examples/svelte/simple/svelte.config.js @@ -1,7 +1,7 @@ -import sveltePreprocess from 'svelte-preprocess' +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' export default { // Consult https://github.com/sveltejs/svelte-preprocess // for more information about preprocessors - preprocess: sveltePreprocess() + preprocess: vitePreprocess() } diff --git a/packages/svelte-query/package.json b/packages/svelte-query/package.json index 36d927ab31..1168cc866a 100644 --- a/packages/svelte-query/package.json +++ b/packages/svelte-query/package.json @@ -15,17 +15,16 @@ "type": "module", "scripts": { "clean": "rimraf ./build", - "test:types": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", - "test:eslint": "svelte-kit sync && eslint --ext .svelte,.ts ./src", - "test:lib": "svelte-kit sync && vitest run --coverage true", - "test:lib:dev": "svelte-kit sync && vitest watch", - "test:lib:publish": "svelte-kit sync && vitest run --coverage false", - "build": "svelte-kit sync && svelte-package && rimraf ./build/lib/package.json" + "test:types": "svelte-check --tsconfig ./tsconfig.json", + "test:eslint": "eslint --ext .svelte,.ts ./src", + "test:lib": "vitest run --coverage true", + "test:lib:dev": "vitest watch", + "test:lib:publish": "vitest run --coverage false", + "build": "svelte-package && rimraf ./build/lib/package.json" }, "devDependencies": { - "@sveltejs/adapter-auto": "^1.0.0", - "@sveltejs/kit": "^1.0.0", "@sveltejs/package": "^1.0.0", + "@sveltejs/vite-plugin-svelte": "^2.0.2", "@testing-library/svelte": "^3.2.2", "@vitest/coverage-istanbul": "^0.26.3", "eslint-plugin-svelte": "^2.14.1", diff --git a/packages/svelte-query/src/lib/Hydrate.svelte b/packages/svelte-query/src/Hydrate.svelte similarity index 100% rename from packages/svelte-query/src/lib/Hydrate.svelte rename to packages/svelte-query/src/Hydrate.svelte diff --git a/packages/svelte-query/src/lib/QueryClientProvider.svelte b/packages/svelte-query/src/QueryClientProvider.svelte similarity index 100% rename from packages/svelte-query/src/lib/QueryClientProvider.svelte rename to packages/svelte-query/src/QueryClientProvider.svelte diff --git a/packages/svelte-query/src/__tests__/CreateMutation.svelte b/packages/svelte-query/src/__tests__/CreateMutation.svelte index 88adbe29a2..3442d390a1 100644 --- a/packages/svelte-query/src/__tests__/CreateMutation.svelte +++ b/packages/svelte-query/src/__tests__/CreateMutation.svelte @@ -1,6 +1,6 @@ + + +``` + +To solve this, you can prefix the query with `$: ` to tell the compiler it should be reactive. + +```markdown + + + +``` diff --git a/examples/svelte/auto-refetching/src/routes/+page.svelte b/examples/svelte/auto-refetching/src/routes/+page.svelte index 62caf36a6f..b29f938861 100644 --- a/examples/svelte/auto-refetching/src/routes/+page.svelte +++ b/examples/svelte/auto-refetching/src/routes/+page.svelte @@ -12,7 +12,7 @@ const endpoint = 'http://localhost:5173/api/data' - const todos = createQuery<{ items: string[] }, Error>({ + $: todos = createQuery<{ items: string[] }, Error>({ queryKey: ['refetch'], queryFn: async () => await fetch(endpoint).then((r) => r.json()), // Refetch the data every second diff --git a/examples/svelte/infinite-loadmore/.gitignore b/examples/svelte/load-more-infinite-scroll/.gitignore similarity index 100% rename from examples/svelte/infinite-loadmore/.gitignore rename to examples/svelte/load-more-infinite-scroll/.gitignore diff --git a/examples/svelte/infinite-loadmore/README.md b/examples/svelte/load-more-infinite-scroll/README.md similarity index 100% rename from examples/svelte/infinite-loadmore/README.md rename to examples/svelte/load-more-infinite-scroll/README.md diff --git a/examples/svelte/infinite-loadmore/index.html b/examples/svelte/load-more-infinite-scroll/index.html similarity index 100% rename from examples/svelte/infinite-loadmore/index.html rename to examples/svelte/load-more-infinite-scroll/index.html diff --git a/examples/svelte/infinite-loadmore/package.json b/examples/svelte/load-more-infinite-scroll/package.json similarity index 88% rename from examples/svelte/infinite-loadmore/package.json rename to examples/svelte/load-more-infinite-scroll/package.json index ef04ab2da0..eb914d6068 100644 --- a/examples/svelte/infinite-loadmore/package.json +++ b/examples/svelte/load-more-infinite-scroll/package.json @@ -1,5 +1,5 @@ { - "name": "@tanstack/query-example-svelte-infinite-loadmore", + "name": "@tanstack/query-example-svelte-load-more-infinite-scroll", "private": true, "version": "0.0.0", "type": "module", diff --git a/examples/svelte/infinite-loadmore/public/emblem-light.svg b/examples/svelte/load-more-infinite-scroll/public/emblem-light.svg similarity index 100% rename from examples/svelte/infinite-loadmore/public/emblem-light.svg rename to examples/svelte/load-more-infinite-scroll/public/emblem-light.svg diff --git a/examples/svelte/infinite-loadmore/src/App.svelte b/examples/svelte/load-more-infinite-scroll/src/App.svelte similarity index 100% rename from examples/svelte/infinite-loadmore/src/App.svelte rename to examples/svelte/load-more-infinite-scroll/src/App.svelte diff --git a/examples/svelte/infinite-loadmore/src/app.css b/examples/svelte/load-more-infinite-scroll/src/app.css similarity index 100% rename from examples/svelte/infinite-loadmore/src/app.css rename to examples/svelte/load-more-infinite-scroll/src/app.css diff --git a/examples/svelte/infinite-loadmore/src/assets/svelte.svg b/examples/svelte/load-more-infinite-scroll/src/assets/svelte.svg similarity index 100% rename from examples/svelte/infinite-loadmore/src/assets/svelte.svg rename to examples/svelte/load-more-infinite-scroll/src/assets/svelte.svg diff --git a/examples/svelte/infinite-loadmore/src/lib/LoadMore.svelte b/examples/svelte/load-more-infinite-scroll/src/lib/LoadMore.svelte similarity index 100% rename from examples/svelte/infinite-loadmore/src/lib/LoadMore.svelte rename to examples/svelte/load-more-infinite-scroll/src/lib/LoadMore.svelte diff --git a/examples/svelte/infinite-loadmore/src/main.ts b/examples/svelte/load-more-infinite-scroll/src/main.ts similarity index 100% rename from examples/svelte/infinite-loadmore/src/main.ts rename to examples/svelte/load-more-infinite-scroll/src/main.ts diff --git a/examples/svelte/infinite-loadmore/src/vite-env.d.ts b/examples/svelte/load-more-infinite-scroll/src/vite-env.d.ts similarity index 100% rename from examples/svelte/infinite-loadmore/src/vite-env.d.ts rename to examples/svelte/load-more-infinite-scroll/src/vite-env.d.ts diff --git a/examples/svelte/infinite-loadmore/svelte.config.js b/examples/svelte/load-more-infinite-scroll/svelte.config.js similarity index 100% rename from examples/svelte/infinite-loadmore/svelte.config.js rename to examples/svelte/load-more-infinite-scroll/svelte.config.js diff --git a/examples/svelte/infinite-loadmore/tsconfig.json b/examples/svelte/load-more-infinite-scroll/tsconfig.json similarity index 100% rename from examples/svelte/infinite-loadmore/tsconfig.json rename to examples/svelte/load-more-infinite-scroll/tsconfig.json diff --git a/examples/svelte/infinite-loadmore/tsconfig.node.json b/examples/svelte/load-more-infinite-scroll/tsconfig.node.json similarity index 100% rename from examples/svelte/infinite-loadmore/tsconfig.node.json rename to examples/svelte/load-more-infinite-scroll/tsconfig.node.json diff --git a/examples/svelte/infinite-loadmore/vite.config.ts b/examples/svelte/load-more-infinite-scroll/vite.config.ts similarity index 100% rename from examples/svelte/infinite-loadmore/vite.config.ts rename to examples/svelte/load-more-infinite-scroll/vite.config.ts diff --git a/examples/svelte/star-wars/src/routes/films/+page.svelte b/examples/svelte/star-wars/src/routes/films/+page.svelte index 3a7cb24713..45069a3da8 100644 --- a/examples/svelte/star-wars/src/routes/films/+page.svelte +++ b/examples/svelte/star-wars/src/routes/films/+page.svelte @@ -6,7 +6,7 @@ return await res.json() } - const query = createQuery({ + query = createQuery({ queryKey: ['films'], queryFn: getFilms, }) diff --git a/packages/svelte-query/src/createBaseQuery.ts b/packages/svelte-query/src/createBaseQuery.ts index 0948911537..401dfc51e2 100644 --- a/packages/svelte-query/src/createBaseQuery.ts +++ b/packages/svelte-query/src/createBaseQuery.ts @@ -3,7 +3,7 @@ import { type QueryKey, type QueryObserver, } from '@tanstack/query-core' -import type { CreateBaseQueryOptions } from './types' +import type { CreateBaseQueryOptions, CreateBaseQueryResult } from './types' import { useQueryClient } from './useQueryClient' import { derived, readable } from 'svelte/store' @@ -22,7 +22,7 @@ export function createBaseQuery< TQueryKey >, Observer: typeof QueryObserver, -) { +): CreateBaseQueryResult { const queryClient = useQueryClient() const defaultedOptions = queryClient.defaultQueryOptions(options) defaultedOptions._optimisticResults = 'optimistic' diff --git a/packages/svelte-query/src/createMutation.ts b/packages/svelte-query/src/createMutation.ts index f2cc43e3f3..532bc50722 100644 --- a/packages/svelte-query/src/createMutation.ts +++ b/packages/svelte-query/src/createMutation.ts @@ -9,7 +9,7 @@ import { import type { UseMutateFunction, CreateMutationOptions, - MutationStoreResult, + CreateMutationResult, } from './types' import { useQueryClient } from './useQueryClient' @@ -20,7 +20,7 @@ export function createMutation< TContext = unknown, >( options: CreateMutationOptions, -): MutationStoreResult +): CreateMutationResult export function createMutation< TData = unknown, @@ -33,7 +33,7 @@ export function createMutation< CreateMutationOptions, 'mutationFn' >, -): MutationStoreResult +): CreateMutationResult export function createMutation< TData = unknown, @@ -46,7 +46,7 @@ export function createMutation< CreateMutationOptions, 'mutationKey' >, -): MutationStoreResult +): CreateMutationResult export function createMutation< TData = unknown, @@ -60,7 +60,7 @@ export function createMutation< CreateMutationOptions, 'mutationKey' | 'mutationFn' >, -): MutationStoreResult +): CreateMutationResult export function createMutation< TData = unknown, @@ -76,7 +76,7 @@ export function createMutation< | MutationFunction | CreateMutationOptions, arg3?: CreateMutationOptions, -): MutationStoreResult { +): CreateMutationResult { const options = parseMutationArgs(arg1, arg2, arg3) const queryClient = useQueryClient() let observer = new MutationObserver( diff --git a/packages/svelte-query/src/createQuery.ts b/packages/svelte-query/src/createQuery.ts index fcfa873943..da26283b20 100644 --- a/packages/svelte-query/src/createQuery.ts +++ b/packages/svelte-query/src/createQuery.ts @@ -4,7 +4,7 @@ import { createBaseQuery } from './createBaseQuery' import type { DefinedCreateQueryResult, CreateQueryOptions, - CreateQueryStoreResult, + CreateQueryResult, } from './types' export function createQuery< @@ -19,7 +19,7 @@ export function createQuery< > & { initialData?: () => undefined }, -): CreateQueryStoreResult +): CreateQueryResult export function createQuery< TQueryFnData = unknown, @@ -42,7 +42,7 @@ export function createQuery< TQueryKey extends QueryKey = QueryKey, >( options: CreateQueryOptions, -): CreateQueryStoreResult +): CreateQueryResult export function createQuery< TQueryFnData = unknown, @@ -55,7 +55,7 @@ export function createQuery< CreateQueryOptions, 'queryKey' | 'initialData' > & { initialData?: () => undefined }, -): CreateQueryStoreResult +): CreateQueryResult export function createQuery< TQueryFnData = unknown, @@ -81,7 +81,7 @@ export function createQuery< CreateQueryOptions, 'queryKey' >, -): CreateQueryStoreResult +): CreateQueryResult export function createQuery< TQueryFnData = unknown, @@ -95,7 +95,7 @@ export function createQuery< CreateQueryOptions, 'queryKey' | 'queryFn' | 'initialData' > & { initialData?: () => undefined }, -): CreateQueryStoreResult +): CreateQueryResult export function createQuery< TQueryFnData = unknown, @@ -123,7 +123,7 @@ export function createQuery< CreateQueryOptions, 'queryKey' | 'queryFn' >, -): CreateQueryStoreResult +): CreateQueryResult export function createQuery< TQueryFnData, @@ -136,7 +136,7 @@ export function createQuery< | QueryFunction | CreateQueryOptions, arg3?: CreateQueryOptions, -): CreateQueryStoreResult { +): CreateQueryResult { const parsedOptions = parseQueryArgs(arg1, arg2, arg3) const result = createBaseQuery(parsedOptions, QueryObserver) return result diff --git a/packages/svelte-query/src/types.ts b/packages/svelte-query/src/types.ts index 032ae6cd7d..76760dfc8d 100644 --- a/packages/svelte-query/src/types.ts +++ b/packages/svelte-query/src/types.ts @@ -28,6 +28,9 @@ export interface CreateBaseQueryOptions< > extends ContextOptions, QueryObserverOptions {} +export interface CreateBaseQueryResult + extends Readable> {} + export interface CreateQueryOptions< TQueryFnData = unknown, TError = unknown, @@ -41,6 +44,9 @@ export interface CreateQueryOptions< TQueryKey > {} +export interface CreateQueryResult + extends CreateBaseQueryResult {} + export interface CreateInfiniteQueryOptions< TQueryFnData = unknown, TError = unknown, @@ -60,28 +66,6 @@ export type CreateInfiniteQueryResult< TError = unknown, > = Readable> -export interface CreateInfiniteQueryStoreResult< - TQueryFnData = unknown, - TError = unknown, - TData = TQueryFnData, -> extends Readable> {} - -export type CreateBaseQueryResult< - TData = unknown, - TError = unknown, -> = QueryObserverResult - -export type CreateQueryResult< - TData = unknown, - TError = unknown, -> = CreateBaseQueryResult - -export interface CreateQueryStoreResult< - TQueryFnData = unknown, - TError = unknown, - TData = TQueryFnData, -> extends Readable> {} - export type DefinedCreateBaseQueryResult< TData = unknown, TError = unknown, @@ -129,18 +113,13 @@ export type UseBaseMutationResult< { mutate: UseMutateFunction } > & { mutateAsync: UseMutateAsyncFunction } -export type CreateMutationResult< +export interface CreateMutationResult< TData = unknown, TError = unknown, TVariables = unknown, TContext = unknown, -> = UseBaseMutationResult - -export interface MutationStoreResult< - TData = unknown, - TError = unknown, - TVariables = unknown, - TContext = unknown, -> extends Readable> {} +> extends Readable< + UseBaseMutationResult + > {} type Override = { [K in keyof A]: K extends keyof B ? B[K] : A[K] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bf1273685c..624b63853b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -703,7 +703,7 @@ importers: typescript: 4.8.4 vite: 4.0.4 - examples/svelte/infinite-loadmore: + examples/svelte/load-more-infinite-scroll: specifiers: '@sveltejs/vite-plugin-svelte': ^2.0.2 '@tanstack/svelte-query': ^4.12.0 From 2ecf24ddcd2330eff0776ddef3a8f3c7f885d4cd Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Thu, 12 Jan 2023 15:48:59 +0000 Subject: [PATCH 13/37] release: v4.22.2 --- packages/svelte-query/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/svelte-query/package.json b/packages/svelte-query/package.json index f664941742..1bccc66efb 100644 --- a/packages/svelte-query/package.json +++ b/packages/svelte-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/svelte-query", - "version": "4.22.1", + "version": "4.22.2", "description": "Primitives for managing, caching and syncing asynchronous and remote data in Svelte", "author": "Dre Johnson", "license": "MIT", From c05bb9104c5d7fde04e54c15bfd12c041529a762 Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Fri, 13 Jan 2023 19:08:49 +1100 Subject: [PATCH 14/37] docs(svelte-query): Expand SSR docs (#4809) * docs(svelte-query): Expand SSR docs * Expand wording * Run prettier --- docs/svelte/ssr.md | 10 ++++++++++ .../svelte/auto-refetching/src/routes/+layout.ts | 1 + examples/svelte/hydration/src/routes/+layout.ts | 1 + .../src/routes/+layout.ts | 1 + examples/svelte/playground/src/routes/+layout.ts | 1 + examples/svelte/star-wars/src/routes/+layout.ts | 1 + .../svelte/star-wars/src/routes/films/+page.svelte | 2 +- packages/svelte-query/static/emblem-light.svg | 13 ------------- 8 files changed, 16 insertions(+), 14 deletions(-) create mode 100644 examples/svelte/auto-refetching/src/routes/+layout.ts create mode 100644 examples/svelte/hydration/src/routes/+layout.ts create mode 100644 examples/svelte/optimistic-updates-typescript/src/routes/+layout.ts create mode 100644 examples/svelte/playground/src/routes/+layout.ts create mode 100644 examples/svelte/star-wars/src/routes/+layout.ts delete mode 100644 packages/svelte-query/static/emblem-light.svg diff --git a/docs/svelte/ssr.md b/docs/svelte/ssr.md index 956f6135c1..40e0fde3da 100644 --- a/docs/svelte/ssr.md +++ b/docs/svelte/ssr.md @@ -5,6 +5,14 @@ title: SSR and SvelteKit Svelte Query supports two ways of prefetching data on the server and passing that to the client with SvelteKit. +## Caveat + +SvelteKit defaults to rendering routes with SSR. Unless you are using one of the below solutions, you need to disable the query on the server. Otherwise, your query will continue executing on the server asynchronously, even after the HTML has been sent to the client. + +One way to achieve this is to `import { browser } from '$app/environment'` and add `enabled: browser` to the options of `createQuery`. This will set the query to disabled on the server, but enabled on the client. + +Another way to achieve this is using page options. For that page or layout, you should set `export const ssr = false` in either `+page.ts` or `+layout.ts`. You can read more about using this option [here](https://kit.svelte.dev/docs/page-options#ssr). + ## Using `initialData` Together with SvelteKit's [`load`](https://kit.svelte.dev/docs/load), you can pass the data loaded server-side into `createQuery`'s' `initialData` option: @@ -38,6 +46,7 @@ export const load: PageLoad = async () => { Pros: - This setup is minimal and this can be a quick solution for some cases +- Works with both `+page.ts`/`+layout.ts` and `+page.server.ts`/`+layout.server.ts` load functions Cons: @@ -108,3 +117,4 @@ Pros: Cons: - Requires more files for initial setup +- Works with only `+page.ts`/`+layout.ts` load functions diff --git a/examples/svelte/auto-refetching/src/routes/+layout.ts b/examples/svelte/auto-refetching/src/routes/+layout.ts new file mode 100644 index 0000000000..62ad4e4f47 --- /dev/null +++ b/examples/svelte/auto-refetching/src/routes/+layout.ts @@ -0,0 +1 @@ +export const ssr = false diff --git a/examples/svelte/hydration/src/routes/+layout.ts b/examples/svelte/hydration/src/routes/+layout.ts new file mode 100644 index 0000000000..b40fb51719 --- /dev/null +++ b/examples/svelte/hydration/src/routes/+layout.ts @@ -0,0 +1 @@ +export const ssr = true diff --git a/examples/svelte/optimistic-updates-typescript/src/routes/+layout.ts b/examples/svelte/optimistic-updates-typescript/src/routes/+layout.ts new file mode 100644 index 0000000000..62ad4e4f47 --- /dev/null +++ b/examples/svelte/optimistic-updates-typescript/src/routes/+layout.ts @@ -0,0 +1 @@ +export const ssr = false diff --git a/examples/svelte/playground/src/routes/+layout.ts b/examples/svelte/playground/src/routes/+layout.ts new file mode 100644 index 0000000000..62ad4e4f47 --- /dev/null +++ b/examples/svelte/playground/src/routes/+layout.ts @@ -0,0 +1 @@ +export const ssr = false diff --git a/examples/svelte/star-wars/src/routes/+layout.ts b/examples/svelte/star-wars/src/routes/+layout.ts new file mode 100644 index 0000000000..62ad4e4f47 --- /dev/null +++ b/examples/svelte/star-wars/src/routes/+layout.ts @@ -0,0 +1 @@ +export const ssr = false diff --git a/examples/svelte/star-wars/src/routes/films/+page.svelte b/examples/svelte/star-wars/src/routes/films/+page.svelte index 45069a3da8..3a7cb24713 100644 --- a/examples/svelte/star-wars/src/routes/films/+page.svelte +++ b/examples/svelte/star-wars/src/routes/films/+page.svelte @@ -6,7 +6,7 @@ return await res.json() } - query = createQuery({ + const query = createQuery({ queryKey: ['films'], queryFn: getFilms, }) diff --git a/packages/svelte-query/static/emblem-light.svg b/packages/svelte-query/static/emblem-light.svg deleted file mode 100644 index a58e69ad5e..0000000000 --- a/packages/svelte-query/static/emblem-light.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - emblem-light - Created with Sketch. - - - - - - - - \ No newline at end of file From 67723337f3a0ea632ad823e9ba55562c01af2ee9 Mon Sep 17 00:00:00 2001 From: Joseph Markus Date: Fri, 13 Jan 2023 12:06:21 +0000 Subject: [PATCH 15/37] docs: Update devtools.md with note that mutations are not tracked (#4810) This can save others some time browsing around trying to get it to work --- docs/react/devtools.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/react/devtools.md b/docs/react/devtools.md index db6b2e0f7b..54984d7fa1 100644 --- a/docs/react/devtools.md +++ b/docs/react/devtools.md @@ -9,6 +9,8 @@ When you begin your React Query journey, you'll want these devtools by your side > Please note that for now, the devtools **do not support React Native**. If you would like to help us make the devtools platform agnostic, please let us know! +> Also note that you can use these devtools to observe queries, but **not mutations** + ## Install and Import the Devtools The devtools are a separate package that you need to install: From 3a3d871ad88feada9e0396168cfa91a0bb58c1f3 Mon Sep 17 00:00:00 2001 From: Ben Longo <11063448+benlongo@users.noreply.github.com> Date: Fri, 13 Jan 2023 07:45:15 -0500 Subject: [PATCH 16/37] docs: clarify interaction of query filter predicates with other criteria (#4532) * docs: clarify interaction of query filter predicates with other criteria * Update docs/guides/filters.md Co-authored-by: Dominik Dorfmeister * Update docs/guides/filters.md Co-authored-by: Dominik Dorfmeister Co-authored-by: Dominik Dorfmeister --- docs/react/guides/filters.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/react/guides/filters.md b/docs/react/guides/filters.md index 1b094442ad..e1588cd3aa 100644 --- a/docs/react/guides/filters.md +++ b/docs/react/guides/filters.md @@ -41,7 +41,7 @@ A query filter object supports the following properties: - When set to `paused` it will match queries that wanted to fetch, but have been `paused`. - When set to `idle` it will match queries that are not fetching. - `predicate?: (query: Query) => boolean` - - This predicate function will be called for every single query in the cache and be expected to return truthy for queries that are `found`. + - This predicate function will be used as a final filter on all matching queries. If no other filters are specified, this function will be evaluated against every query in the cache. ## `Mutation Filters` @@ -62,12 +62,12 @@ await queryClient.isMutating({ A mutation filter object supports the following properties: +- `mutationKey?: MutationKey` + - Set this property to define a mutation key to match on. - `exact?: boolean` - If you don't want to search mutations inclusively by mutation key, you can pass the `exact: true` option to return only the mutation with the exact mutation key you have passed. - `fetching?: boolean` - When set to `true` it will match mutations that are currently fetching. - When set to `false` it will match mutations that are not fetching. - `predicate?: (mutation: Mutation) => boolean` - - This predicate function will be called for every single mutation in the cache and be expected to return truthy for mutations that are `found`. -- `mutationKey?: MutationKey` - - Set this property to define a mutation key to match on. + - This predicate function will be used as a final filter on all matching mutations. If no other filters are specified, this function will be evaluated against every mutation in the cache. From 2cd92ef39182a5602c72baa0e3a0929d8faa9a46 Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Fri, 13 Jan 2023 23:48:19 +1100 Subject: [PATCH 17/37] docs(svelte-query): Rework SvelteKit setup (#4811) * Add some default options * Rewrite hydration example * Run prettier * Rename example to SSR * Add recommended SvelteKit setup * Rework infinite scroll in sveltekit * Add SvelteKit note to overview * Switch basic example to sveltekit Co-authored-by: Dominik Dorfmeister --- docs/config.json | 8 +-- docs/svelte/overview.md | 5 ++ docs/svelte/ssr.md | 42 +++++++++++--- examples/svelte/auto-refetching/package.json | 8 +-- .../auto-refetching/src/routes/+layout.svelte | 9 ++- .../auto-refetching/src/routes/+layout.ts | 1 - examples/svelte/basic/.gitignore | 29 +++------- examples/svelte/basic/README.md | 58 ++++++++----------- examples/svelte/basic/index.html | 13 ----- examples/svelte/basic/package.json | 12 ++-- examples/svelte/basic/src/App.svelte | 13 ----- examples/svelte/basic/src/app.css | 12 ++-- .../svelte/{hydration => basic}/src/app.d.ts | 0 .../svelte/{hydration => basic}/src/app.html | 0 examples/svelte/basic/src/assets/svelte.svg | 1 - .../svelte/basic/src/lib/BasicQuery.svelte | 15 ----- examples/svelte/basic/src/lib/Post.svelte | 11 ++-- examples/svelte/basic/src/lib/Posts.svelte | 9 ++- examples/svelte/basic/src/lib/data.ts | 21 ++++--- examples/svelte/basic/src/lib/types.ts | 5 ++ examples/svelte/basic/src/main.ts | 8 --- .../svelte/basic/src/routes/+layout.svelte | 19 ++++++ examples/svelte/basic/src/routes/+page.svelte | 6 ++ .../basic/src/routes/[postId]/+page.svelte | 8 +++ .../svelte/basic/src/routes/[postId]/+page.ts | 6 ++ examples/svelte/basic/src/vite-env.d.ts | 2 - .../basic/{public => static}/emblem-light.svg | 0 examples/svelte/basic/svelte.config.js | 16 +++-- examples/svelte/basic/tsconfig.json | 28 ++++----- examples/svelte/basic/tsconfig.node.json | 8 --- examples/svelte/basic/vite.config.ts | 13 +++-- examples/svelte/hydration/src/lib/data.ts | 16 ----- examples/svelte/hydration/src/lib/store.ts | 4 -- .../hydration/src/routes/+layout.svelte | 19 ------ .../svelte/hydration/src/routes/+layout.ts | 1 - .../svelte/hydration/src/routes/+page.svelte | 31 ---------- examples/svelte/hydration/src/routes/+page.ts | 16 ----- .../hydration/src/routes/api/data/+server.ts | 29 ---------- .../load-more-infinite-scroll/.gitignore | 32 +++------- .../load-more-infinite-scroll/README.md | 58 ++++++++----------- .../load-more-infinite-scroll/index.html | 13 ----- .../load-more-infinite-scroll/package.json | 12 ++-- .../load-more-infinite-scroll/src/App.svelte | 13 ----- .../load-more-infinite-scroll/src/app.d.ts | 9 +++ .../load-more-infinite-scroll/src/app.html | 12 ++++ .../src/assets/svelte.svg | 1 - .../load-more-infinite-scroll/src/main.ts | 8 --- .../src/routes/+layout.svelte | 19 ++++++ .../src/routes/+page.svelte | 6 ++ .../src/vite-env.d.ts | 2 - .../static/emblem-light.svg | 0 .../svelte.config.js | 18 ++++-- .../load-more-infinite-scroll/tsconfig.json | 28 ++++----- .../tsconfig.node.json | 8 --- .../load-more-infinite-scroll/vite.config.ts | 13 +++-- .../package.json | 8 +-- .../src/routes/+layout.svelte | 9 ++- .../src/routes/+layout.ts | 1 - examples/svelte/playground/package.json | 2 +- .../playground/src/routes/+layout.svelte | 9 ++- .../svelte/playground/src/routes/+layout.ts | 1 - examples/svelte/simple/package.json | 4 +- examples/svelte/{hydration => ssr}/.gitignore | 0 examples/svelte/{hydration => ssr}/README.md | 0 .../svelte/{hydration => ssr}/package.json | 10 ++-- .../svelte/{hydration => ssr}/src/app.css | 10 ++-- examples/svelte/ssr/src/app.d.ts | 9 +++ examples/svelte/ssr/src/app.html | 11 ++++ .../{hydration => ssr}/src/lib/Post.svelte | 11 ++-- .../{hydration => ssr}/src/lib/Posts.svelte | 9 ++- examples/svelte/ssr/src/lib/data.ts | 15 +++++ examples/svelte/ssr/src/lib/types.ts | 5 ++ examples/svelte/ssr/src/routes/+layout.svelte | 13 +++++ examples/svelte/ssr/src/routes/+layout.ts | 15 +++++ examples/svelte/ssr/src/routes/+page.svelte | 6 ++ examples/svelte/ssr/src/routes/+page.ts | 11 ++++ .../ssr/src/routes/[postId]/+page.svelte | 8 +++ .../svelte/ssr/src/routes/[postId]/+page.ts | 15 +++++ .../public => ssr/static}/emblem-light.svg | 0 .../{hydration => ssr}/svelte.config.js | 0 .../svelte/{hydration => ssr}/tsconfig.json | 0 .../svelte/{hydration => ssr}/vite.config.ts | 0 examples/svelte/star-wars/package.json | 2 +- .../star-wars/src/routes/+layout.svelte | 15 +++-- .../svelte/star-wars/src/routes/+layout.ts | 1 - pnpm-lock.yaml | 58 +++++++++---------- 86 files changed, 498 insertions(+), 514 deletions(-) delete mode 100644 examples/svelte/auto-refetching/src/routes/+layout.ts delete mode 100644 examples/svelte/basic/index.html delete mode 100644 examples/svelte/basic/src/App.svelte rename examples/svelte/{hydration => basic}/src/app.d.ts (100%) rename examples/svelte/{hydration => basic}/src/app.html (100%) delete mode 100644 examples/svelte/basic/src/assets/svelte.svg delete mode 100644 examples/svelte/basic/src/lib/BasicQuery.svelte create mode 100644 examples/svelte/basic/src/lib/types.ts delete mode 100644 examples/svelte/basic/src/main.ts create mode 100644 examples/svelte/basic/src/routes/+layout.svelte create mode 100644 examples/svelte/basic/src/routes/+page.svelte create mode 100644 examples/svelte/basic/src/routes/[postId]/+page.svelte create mode 100644 examples/svelte/basic/src/routes/[postId]/+page.ts delete mode 100644 examples/svelte/basic/src/vite-env.d.ts rename examples/svelte/basic/{public => static}/emblem-light.svg (100%) delete mode 100644 examples/svelte/basic/tsconfig.node.json delete mode 100644 examples/svelte/hydration/src/lib/data.ts delete mode 100644 examples/svelte/hydration/src/lib/store.ts delete mode 100644 examples/svelte/hydration/src/routes/+layout.svelte delete mode 100644 examples/svelte/hydration/src/routes/+layout.ts delete mode 100644 examples/svelte/hydration/src/routes/+page.svelte delete mode 100644 examples/svelte/hydration/src/routes/+page.ts delete mode 100644 examples/svelte/hydration/src/routes/api/data/+server.ts delete mode 100644 examples/svelte/load-more-infinite-scroll/index.html delete mode 100644 examples/svelte/load-more-infinite-scroll/src/App.svelte create mode 100644 examples/svelte/load-more-infinite-scroll/src/app.d.ts create mode 100644 examples/svelte/load-more-infinite-scroll/src/app.html delete mode 100644 examples/svelte/load-more-infinite-scroll/src/assets/svelte.svg delete mode 100644 examples/svelte/load-more-infinite-scroll/src/main.ts create mode 100644 examples/svelte/load-more-infinite-scroll/src/routes/+layout.svelte create mode 100644 examples/svelte/load-more-infinite-scroll/src/routes/+page.svelte delete mode 100644 examples/svelte/load-more-infinite-scroll/src/vite-env.d.ts rename examples/svelte/{hydration => load-more-infinite-scroll}/static/emblem-light.svg (100%) delete mode 100644 examples/svelte/load-more-infinite-scroll/tsconfig.node.json delete mode 100644 examples/svelte/optimistic-updates-typescript/src/routes/+layout.ts delete mode 100644 examples/svelte/playground/src/routes/+layout.ts rename examples/svelte/{hydration => ssr}/.gitignore (100%) rename examples/svelte/{hydration => ssr}/README.md (100%) rename examples/svelte/{hydration => ssr}/package.json (79%) rename examples/svelte/{hydration => ssr}/src/app.css (94%) create mode 100644 examples/svelte/ssr/src/app.d.ts create mode 100644 examples/svelte/ssr/src/app.html rename examples/svelte/{hydration => ssr}/src/lib/Post.svelte (68%) rename examples/svelte/{hydration => ssr}/src/lib/Posts.svelte (88%) create mode 100644 examples/svelte/ssr/src/lib/data.ts create mode 100644 examples/svelte/ssr/src/lib/types.ts create mode 100644 examples/svelte/ssr/src/routes/+layout.svelte create mode 100644 examples/svelte/ssr/src/routes/+layout.ts create mode 100644 examples/svelte/ssr/src/routes/+page.svelte create mode 100644 examples/svelte/ssr/src/routes/+page.ts create mode 100644 examples/svelte/ssr/src/routes/[postId]/+page.svelte create mode 100644 examples/svelte/ssr/src/routes/[postId]/+page.ts rename examples/svelte/{load-more-infinite-scroll/public => ssr/static}/emblem-light.svg (100%) rename examples/svelte/{hydration => ssr}/svelte.config.js (100%) rename examples/svelte/{hydration => ssr}/tsconfig.json (100%) rename examples/svelte/{hydration => ssr}/vite.config.ts (100%) delete mode 100644 examples/svelte/star-wars/src/routes/+layout.ts diff --git a/docs/config.json b/docs/config.json index 48ffb31ff4..95329df12e 100644 --- a/docs/config.json +++ b/docs/config.json @@ -720,6 +720,10 @@ "label": "Auto Refetching / Polling / Realtime", "to": "svelte/examples/svelte/auto-refetching" }, + { + "label": "SSR", + "to": "svelte/examples/svelte/ssr" + }, { "label": "Optimistic Updates in TypeScript", "to": "svelte/examples/svelte/optimistic-updates-typescript" @@ -735,10 +739,6 @@ { "label": "Infinite Queries", "to": "svelte/examples/svelte/load-more-infinite-scroll" - }, - { - "label": "Hydration", - "to": "svelte/examples/svelte/hydration" } ] } diff --git a/docs/svelte/overview.md b/docs/svelte/overview.md index 54676713e3..79e40a8c53 100644 --- a/docs/svelte/overview.md +++ b/docs/svelte/overview.md @@ -47,6 +47,10 @@ Then call any function (e.g. createQuery) from any component: ``` +## SvelteKit + +If you are using SvelteKit, please have a look at [SSR & SvelteKit](./ssr). + ## Available Functions Svelte Query offers useful functions and components that will make managing server state in Svelte apps easier. @@ -67,3 +71,4 @@ Svelte Query offers useful functions and components that will make managing serv Svelte Query offers an API similar to React Query, but there are some key differences to be mindful of. - Many of the functions in Svelte Query return a Svelte store. To access values on these stores reactively, you need to prefix the store with a `$`. You can learn more about Svelte stores [here](https://svelte.dev/tutorial/writable-stores). +- If your query or mutation depends on variables, you must assign it reactively. You can read more about this [here](./reactivity). diff --git a/docs/svelte/ssr.md b/docs/svelte/ssr.md index 40e0fde3da..84e21596be 100644 --- a/docs/svelte/ssr.md +++ b/docs/svelte/ssr.md @@ -3,17 +3,39 @@ id: overview title: SSR and SvelteKit --- -Svelte Query supports two ways of prefetching data on the server and passing that to the client with SvelteKit. +## Setup -## Caveat +SvelteKit defaults to rendering routes with SSR. Because of this, you need to disable the query on the server. Otherwise, your query will continue executing on the server asynchronously, even after the HTML has been sent to the client. -SvelteKit defaults to rendering routes with SSR. Unless you are using one of the below solutions, you need to disable the query on the server. Otherwise, your query will continue executing on the server asynchronously, even after the HTML has been sent to the client. +The recommended way to achieve this is to use the `browser` module from SvelteKit in your `QueryClient` object. This will not disable `queryClient.prefetchQuery()`, which is used in one of the solutions below. -One way to achieve this is to `import { browser } from '$app/environment'` and add `enabled: browser` to the options of `createQuery`. This will set the query to disabled on the server, but enabled on the client. +```markdown + -Another way to achieve this is using page options. For that page or layout, you should set `export const ssr = false` in either `+page.ts` or `+layout.ts`. You can read more about using this option [here](https://kit.svelte.dev/docs/page-options#ssr). + + + +``` -## Using `initialData` +## Prefetching data + +Svelte Query supports two ways of prefetching data on the server and passing that to the client with SvelteKit. + +If you wish to view the ideal SSR setup, please have a look at the [SSR example](../examples/svelte/ssr). + + +### Using `initialData` Together with SvelteKit's [`load`](https://kit.svelte.dev/docs/load), you can pass the data loaded server-side into `createQuery`'s' `initialData` option: @@ -54,11 +76,12 @@ Cons: - If you are calling `createQuery` with the same query in multiple locations, you need to pass `initialData` to all of them - There is no way to know at what time the query was fetched on the server, so `dataUpdatedAt` and determining if the query needs refetching is based on when the page loaded instead -## Using `prefetchQuery` +### Using `prefetchQuery` Svelte Query supports prefetching queries on the server. Using this setup below, you can fetch data and pass it into QueryClientProvider before it is sent to the user's browser. Therefore, this data is already available in the cache, and no initial fetch occurs client-side. **src/routes/+layout.ts** + ```ts import { QueryClient } from '@tanstack/svelte-query' import type { LayoutLoad } from './$types' @@ -70,6 +93,7 @@ export const load: LayoutLoad = async () => { ``` **src/routes/+layout.svelte** + ```markdown diff --git a/examples/svelte/auto-refetching/src/routes/+layout.ts b/examples/svelte/auto-refetching/src/routes/+layout.ts deleted file mode 100644 index 62ad4e4f47..0000000000 --- a/examples/svelte/auto-refetching/src/routes/+layout.ts +++ /dev/null @@ -1 +0,0 @@ -export const ssr = false diff --git a/examples/svelte/basic/.gitignore b/examples/svelte/basic/.gitignore index 59362fd3fa..6fd24c7d48 100644 --- a/examples/svelte/basic/.gitignore +++ b/examples/svelte/basic/.gitignore @@ -1,24 +1,9 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - +.DS_Store node_modules -dist -dist-ssr -*.local +/build +/.svelte-kit +/package +.env +.env.* +!.env.example !lib/ - -# Editor directories and files -.vscode -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git a/examples/svelte/basic/README.md b/examples/svelte/basic/README.md index 4ef762ffec..5c91169b0c 100644 --- a/examples/svelte/basic/README.md +++ b/examples/svelte/basic/README.md @@ -1,48 +1,38 @@ -# Svelte + TS + Vite +# create-svelte -This template should help get you started developing with Svelte and TypeScript in Vite. +Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). -## Recommended IDE Setup +## Creating a project -[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). +If you're seeing this, you've probably already done this step. Congrats! -## Need an official Svelte framework? +```bash +# create a new project in the current directory +npm create svelte@latest -Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. - -## Technical considerations - -**Why use this over SvelteKit?** - -- It brings its own routing solution which might not be preferable for some users. -- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. - `vite dev` and `vite build` wouldn't work in a SvelteKit environment, for example. - -This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. - -Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. - -**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** +# create a new project in my-app +npm create svelte@latest my-app +``` -Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. +## Developing -**Why include `.vscode/extensions.json`?** +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: -Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. +```bash +npm run dev -**Why enable `allowJs` in the TS template?** +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` -While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. +## Building -**Why is HMR not preserving my local component state?** +To create a production version of your app: -HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). +```bash +npm run build +``` -If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. +You can preview the production build with `npm run preview`. -```ts -// store.ts -// An extremely simple external store -import { writable } from 'svelte/store' -export default writable(0) -``` +> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. diff --git a/examples/svelte/basic/index.html b/examples/svelte/basic/index.html deleted file mode 100644 index 8fe436406e..0000000000 --- a/examples/svelte/basic/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Vite + Svelte + TS - - -
- - - diff --git a/examples/svelte/basic/package.json b/examples/svelte/basic/package.json index e109a9256e..49d0649853 100644 --- a/examples/svelte/basic/package.json +++ b/examples/svelte/basic/package.json @@ -1,20 +1,20 @@ { "name": "@tanstack/query-example-svelte-basic", "private": true, - "version": "0.0.0", + "version": "0.0.1", "type": "module", "scripts": { - "dev": "vite", + "dev": "vite dev", "build": "vite build", "preview": "vite preview", - "check": "svelte-check --tsconfig ./tsconfig.json" + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json" }, "dependencies": { - "@tanstack/svelte-query": "^4.12.0" + "@tanstack/svelte-query": "^4.20.0" }, "devDependencies": { - "@sveltejs/vite-plugin-svelte": "^2.0.2", - "@tsconfig/svelte": "^3.0.0", + "@sveltejs/adapter-auto": "^1.0.0", + "@sveltejs/kit": "^1.0.0", "svelte": "^3.54.0", "svelte-check": "^2.9.2", "tslib": "^2.4.1", diff --git a/examples/svelte/basic/src/App.svelte b/examples/svelte/basic/src/App.svelte deleted file mode 100644 index 33c1c6e297..0000000000 --- a/examples/svelte/basic/src/App.svelte +++ /dev/null @@ -1,13 +0,0 @@ - - - -
-

Basic Query

- -
-
diff --git a/examples/svelte/basic/src/app.css b/examples/svelte/basic/src/app.css index bcc7233dd1..d301f1b2a3 100644 --- a/examples/svelte/basic/src/app.css +++ b/examples/svelte/basic/src/app.css @@ -41,14 +41,14 @@ h1 { padding: 2em; } -#app { +main { max-width: 1280px; margin: 0 auto; padding: 2rem; text-align: center; } -button { +.button { border-radius: 8px; border: 1px solid transparent; padding: 0.6em 1.2em; @@ -59,11 +59,11 @@ button { cursor: pointer; transition: border-color 0.25s; } -button:hover { +.button:hover { border-color: #646cff; } -button:focus, -button:focus-visible { +.button:focus, +.button:focus-visible { outline: 4px auto -webkit-focus-ring-color; } @@ -75,7 +75,7 @@ button:focus-visible { a:hover { color: #747bff; } - button { + .button { background-color: #f9f9f9; } } diff --git a/examples/svelte/hydration/src/app.d.ts b/examples/svelte/basic/src/app.d.ts similarity index 100% rename from examples/svelte/hydration/src/app.d.ts rename to examples/svelte/basic/src/app.d.ts diff --git a/examples/svelte/hydration/src/app.html b/examples/svelte/basic/src/app.html similarity index 100% rename from examples/svelte/hydration/src/app.html rename to examples/svelte/basic/src/app.html diff --git a/examples/svelte/basic/src/assets/svelte.svg b/examples/svelte/basic/src/assets/svelte.svg deleted file mode 100644 index c5e08481f8..0000000000 --- a/examples/svelte/basic/src/assets/svelte.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/examples/svelte/basic/src/lib/BasicQuery.svelte b/examples/svelte/basic/src/lib/BasicQuery.svelte deleted file mode 100644 index 3f14271a5b..0000000000 --- a/examples/svelte/basic/src/lib/BasicQuery.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - -{#if postId > -1} - -{:else} - -{/if} diff --git a/examples/svelte/basic/src/lib/Post.svelte b/examples/svelte/basic/src/lib/Post.svelte index 1c13cf4be3..87b0f3234d 100644 --- a/examples/svelte/basic/src/lib/Post.svelte +++ b/examples/svelte/basic/src/lib/Post.svelte @@ -1,22 +1,19 @@
- + Back
{#if !postId || $post.isLoading} Loading... diff --git a/examples/svelte/basic/src/lib/Posts.svelte b/examples/svelte/basic/src/lib/Posts.svelte index 0d3d63dad5..83b4112f66 100644 --- a/examples/svelte/basic/src/lib/Posts.svelte +++ b/examples/svelte/basic/src/lib/Posts.svelte @@ -1,11 +1,11 @@ + + +
+ +
+
diff --git a/examples/svelte/basic/src/routes/+page.svelte b/examples/svelte/basic/src/routes/+page.svelte new file mode 100644 index 0000000000..293f360067 --- /dev/null +++ b/examples/svelte/basic/src/routes/+page.svelte @@ -0,0 +1,6 @@ + + +

Basic Query

+ diff --git a/examples/svelte/basic/src/routes/[postId]/+page.svelte b/examples/svelte/basic/src/routes/[postId]/+page.svelte new file mode 100644 index 0000000000..b68acc0bc0 --- /dev/null +++ b/examples/svelte/basic/src/routes/[postId]/+page.svelte @@ -0,0 +1,8 @@ + + + diff --git a/examples/svelte/basic/src/routes/[postId]/+page.ts b/examples/svelte/basic/src/routes/[postId]/+page.ts new file mode 100644 index 0000000000..ea67748ad4 --- /dev/null +++ b/examples/svelte/basic/src/routes/[postId]/+page.ts @@ -0,0 +1,6 @@ +import type { PageLoad } from './$types' + +export const load: PageLoad = async ({ params }) => { + const postId = parseInt(params.postId) + return { postId } +} diff --git a/examples/svelte/basic/src/vite-env.d.ts b/examples/svelte/basic/src/vite-env.d.ts deleted file mode 100644 index 4078e7476a..0000000000 --- a/examples/svelte/basic/src/vite-env.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// diff --git a/examples/svelte/basic/public/emblem-light.svg b/examples/svelte/basic/static/emblem-light.svg similarity index 100% rename from examples/svelte/basic/public/emblem-light.svg rename to examples/svelte/basic/static/emblem-light.svg diff --git a/examples/svelte/basic/svelte.config.js b/examples/svelte/basic/svelte.config.js index 49c64ac5bf..836e30422d 100644 --- a/examples/svelte/basic/svelte.config.js +++ b/examples/svelte/basic/svelte.config.js @@ -1,7 +1,15 @@ -import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' +import adapter from '@sveltejs/adapter-auto'; +import { vitePreprocess } from '@sveltejs/kit/vite'; -export default { +/** @type {import('@sveltejs/kit').Config} */ +const config = { // Consult https://github.com/sveltejs/svelte-preprocess // for more information about preprocessors - preprocess: vitePreprocess() -} + preprocess: vitePreprocess(), + + kit: { + adapter: adapter() + } +}; + +export default config; diff --git a/examples/svelte/basic/tsconfig.json b/examples/svelte/basic/tsconfig.json index d38303196a..794b95b642 100644 --- a/examples/svelte/basic/tsconfig.json +++ b/examples/svelte/basic/tsconfig.json @@ -1,21 +1,17 @@ { - "extends": "@tsconfig/svelte/tsconfig.json", + "extends": "./.svelte-kit/tsconfig.json", "compilerOptions": { - "target": "ESNext", - "useDefineForClassFields": true, - "module": "ESNext", - "resolveJsonModule": true, - "baseUrl": ".", - /** - * Typecheck JS in `.svelte` and `.js` files by default. - * Disable checkJs if you'd like to use dynamic types in JS. - * Note that setting allowJs false does not prevent the use - * of JS in `.svelte` files. - */ "allowJs": true, "checkJs": true, - "isolatedModules": true - }, - "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], - "references": [{ "path": "./tsconfig.node.json" }] + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true + } + // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in } diff --git a/examples/svelte/basic/tsconfig.node.json b/examples/svelte/basic/tsconfig.node.json deleted file mode 100644 index 65dbdb96ae..0000000000 --- a/examples/svelte/basic/tsconfig.node.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "module": "ESNext", - "moduleResolution": "Node" - }, - "include": ["vite.config.ts"] -} diff --git a/examples/svelte/basic/vite.config.ts b/examples/svelte/basic/vite.config.ts index 401b4d4bd6..f2eb6d93cf 100644 --- a/examples/svelte/basic/vite.config.ts +++ b/examples/svelte/basic/vite.config.ts @@ -1,7 +1,8 @@ -import { defineConfig } from 'vite' -import { svelte } from '@sveltejs/vite-plugin-svelte' +import { sveltekit } from '@sveltejs/kit/vite'; +import type { UserConfig } from 'vite'; -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [svelte()] -}) +const config: UserConfig = { + plugins: [sveltekit()] +}; + +export default config; diff --git a/examples/svelte/hydration/src/lib/data.ts b/examples/svelte/hydration/src/lib/data.ts deleted file mode 100644 index d401b35752..0000000000 --- a/examples/svelte/hydration/src/lib/data.ts +++ /dev/null @@ -1,16 +0,0 @@ -export type Post = { id: number; title: string; body: string } - -export const limit = 10 - -export const getPosts = async (limit: number) => { - const parsed = await fetch('https://jsonplaceholder.typicode.com/posts').then( - (r) => r.json(), - ) - const result = parsed.filter((x: Post) => x.id <= limit) - return result -} - -export const getPostById = async (id: number) => - await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`).then((r) => - r.json(), - ) diff --git a/examples/svelte/hydration/src/lib/store.ts b/examples/svelte/hydration/src/lib/store.ts deleted file mode 100644 index 79ab749fdf..0000000000 --- a/examples/svelte/hydration/src/lib/store.ts +++ /dev/null @@ -1,4 +0,0 @@ -import type { DehydratedState } from '@tanstack/query-core' -import { writable } from 'svelte/store' - -export const dehydratedState = writable() diff --git a/examples/svelte/hydration/src/routes/+layout.svelte b/examples/svelte/hydration/src/routes/+layout.svelte deleted file mode 100644 index 97f28d6ee6..0000000000 --- a/examples/svelte/hydration/src/routes/+layout.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - - - -
- -
-
-
diff --git a/examples/svelte/hydration/src/routes/+layout.ts b/examples/svelte/hydration/src/routes/+layout.ts deleted file mode 100644 index b40fb51719..0000000000 --- a/examples/svelte/hydration/src/routes/+layout.ts +++ /dev/null @@ -1 +0,0 @@ -export const ssr = true diff --git a/examples/svelte/hydration/src/routes/+page.svelte b/examples/svelte/hydration/src/routes/+page.svelte deleted file mode 100644 index 26ce099089..0000000000 --- a/examples/svelte/hydration/src/routes/+page.svelte +++ /dev/null @@ -1,31 +0,0 @@ - - -

Basic Query with Hydration

-{#if postId > -1} - -{:else} - -{/if} - - diff --git a/examples/svelte/hydration/src/routes/+page.ts b/examples/svelte/hydration/src/routes/+page.ts deleted file mode 100644 index e1a3833970..0000000000 --- a/examples/svelte/hydration/src/routes/+page.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { dehydrate, QueryClient } from '@tanstack/svelte-query' -import { getPosts, limit } from '$lib/data.js' -import type { PageLoad } from './$types' - -export const load: PageLoad = async () => { - const queryClient = new QueryClient() - - await queryClient.prefetchQuery({ - queryKey: ['posts', limit], - queryFn: () => getPosts(limit), - }) - - return { - dehydratedState: dehydrate(queryClient), - } -} diff --git a/examples/svelte/hydration/src/routes/api/data/+server.ts b/examples/svelte/hydration/src/routes/api/data/+server.ts deleted file mode 100644 index 301018f5cc..0000000000 --- a/examples/svelte/hydration/src/routes/api/data/+server.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { json, type RequestHandler } from '@sveltejs/kit' - -type Todo = { - id: string - text: string -} - -const items: Todo[] = [] - -/** @type {import('./$types').RequestHandler} */ -export const GET: RequestHandler = async (req) => { - await new Promise((r) => setTimeout(r, 1000)) - return json({ ts: Date.now(), items }, { status: 200 }) -} - -/** @type {import('./$types').RequestHandler} */ -export const POST: RequestHandler = async ({ request }) => { - const { text } = await request.json() - - if (Math.random() > 0.7) { - json({ message: 'Could not add item!' }, { status: 500 }) - } - const newTodo = { - id: Math.random().toString(), - text: text.toUpperCase() as string, - } - items.push(newTodo) - return json(newTodo, { status: 200 }) -} diff --git a/examples/svelte/load-more-infinite-scroll/.gitignore b/examples/svelte/load-more-infinite-scroll/.gitignore index 59362fd3fa..6635cf5542 100644 --- a/examples/svelte/load-more-infinite-scroll/.gitignore +++ b/examples/svelte/load-more-infinite-scroll/.gitignore @@ -1,24 +1,10 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -dist -dist-ssr -*.local -!lib/ - -# Editor directories and files -.vscode -.idea .DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/examples/svelte/load-more-infinite-scroll/README.md b/examples/svelte/load-more-infinite-scroll/README.md index 4ef762ffec..5c91169b0c 100644 --- a/examples/svelte/load-more-infinite-scroll/README.md +++ b/examples/svelte/load-more-infinite-scroll/README.md @@ -1,48 +1,38 @@ -# Svelte + TS + Vite +# create-svelte -This template should help get you started developing with Svelte and TypeScript in Vite. +Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). -## Recommended IDE Setup +## Creating a project -[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). +If you're seeing this, you've probably already done this step. Congrats! -## Need an official Svelte framework? +```bash +# create a new project in the current directory +npm create svelte@latest -Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. - -## Technical considerations - -**Why use this over SvelteKit?** - -- It brings its own routing solution which might not be preferable for some users. -- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. - `vite dev` and `vite build` wouldn't work in a SvelteKit environment, for example. - -This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. - -Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. - -**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** +# create a new project in my-app +npm create svelte@latest my-app +``` -Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. +## Developing -**Why include `.vscode/extensions.json`?** +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: -Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. +```bash +npm run dev -**Why enable `allowJs` in the TS template?** +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` -While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. +## Building -**Why is HMR not preserving my local component state?** +To create a production version of your app: -HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). +```bash +npm run build +``` -If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. +You can preview the production build with `npm run preview`. -```ts -// store.ts -// An extremely simple external store -import { writable } from 'svelte/store' -export default writable(0) -``` +> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. diff --git a/examples/svelte/load-more-infinite-scroll/index.html b/examples/svelte/load-more-infinite-scroll/index.html deleted file mode 100644 index 8fe436406e..0000000000 --- a/examples/svelte/load-more-infinite-scroll/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Vite + Svelte + TS - - -
- - - diff --git a/examples/svelte/load-more-infinite-scroll/package.json b/examples/svelte/load-more-infinite-scroll/package.json index eb914d6068..29f4191601 100644 --- a/examples/svelte/load-more-infinite-scroll/package.json +++ b/examples/svelte/load-more-infinite-scroll/package.json @@ -1,20 +1,20 @@ { "name": "@tanstack/query-example-svelte-load-more-infinite-scroll", "private": true, - "version": "0.0.0", + "version": "0.0.1", "type": "module", "scripts": { - "dev": "vite", + "dev": "vite dev", "build": "vite build", "preview": "vite preview", - "check": "svelte-check --tsconfig ./tsconfig.json" + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json" }, "dependencies": { - "@tanstack/svelte-query": "^4.12.0" + "@tanstack/svelte-query": "^4.20.0" }, "devDependencies": { - "@sveltejs/vite-plugin-svelte": "^2.0.2", - "@tsconfig/svelte": "^3.0.0", + "@sveltejs/adapter-auto": "^1.0.0", + "@sveltejs/kit": "^1.0.0", "svelte": "^3.54.0", "svelte-check": "^2.9.2", "tslib": "^2.4.1", diff --git a/examples/svelte/load-more-infinite-scroll/src/App.svelte b/examples/svelte/load-more-infinite-scroll/src/App.svelte deleted file mode 100644 index 1c3b2c1007..0000000000 --- a/examples/svelte/load-more-infinite-scroll/src/App.svelte +++ /dev/null @@ -1,13 +0,0 @@ - - - -
-

Infinte Load More

- -
-
diff --git a/examples/svelte/load-more-infinite-scroll/src/app.d.ts b/examples/svelte/load-more-infinite-scroll/src/app.d.ts new file mode 100644 index 0000000000..1cea0dcf2b --- /dev/null +++ b/examples/svelte/load-more-infinite-scroll/src/app.d.ts @@ -0,0 +1,9 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +// and what to do when importing types +declare namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface Platform {} +} diff --git a/examples/svelte/load-more-infinite-scroll/src/app.html b/examples/svelte/load-more-infinite-scroll/src/app.html new file mode 100644 index 0000000000..117bd02615 --- /dev/null +++ b/examples/svelte/load-more-infinite-scroll/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/examples/svelte/load-more-infinite-scroll/src/assets/svelte.svg b/examples/svelte/load-more-infinite-scroll/src/assets/svelte.svg deleted file mode 100644 index c5e08481f8..0000000000 --- a/examples/svelte/load-more-infinite-scroll/src/assets/svelte.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/examples/svelte/load-more-infinite-scroll/src/main.ts b/examples/svelte/load-more-infinite-scroll/src/main.ts deleted file mode 100644 index 8a909a15a0..0000000000 --- a/examples/svelte/load-more-infinite-scroll/src/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -import './app.css' -import App from './App.svelte' - -const app = new App({ - target: document.getElementById('app'), -}) - -export default app diff --git a/examples/svelte/load-more-infinite-scroll/src/routes/+layout.svelte b/examples/svelte/load-more-infinite-scroll/src/routes/+layout.svelte new file mode 100644 index 0000000000..8c686d17ed --- /dev/null +++ b/examples/svelte/load-more-infinite-scroll/src/routes/+layout.svelte @@ -0,0 +1,19 @@ + + + +
+ +
+
diff --git a/examples/svelte/load-more-infinite-scroll/src/routes/+page.svelte b/examples/svelte/load-more-infinite-scroll/src/routes/+page.svelte new file mode 100644 index 0000000000..14c2b4abbd --- /dev/null +++ b/examples/svelte/load-more-infinite-scroll/src/routes/+page.svelte @@ -0,0 +1,6 @@ + + +

Infinte Load More

+ diff --git a/examples/svelte/load-more-infinite-scroll/src/vite-env.d.ts b/examples/svelte/load-more-infinite-scroll/src/vite-env.d.ts deleted file mode 100644 index 4078e7476a..0000000000 --- a/examples/svelte/load-more-infinite-scroll/src/vite-env.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// diff --git a/examples/svelte/hydration/static/emblem-light.svg b/examples/svelte/load-more-infinite-scroll/static/emblem-light.svg similarity index 100% rename from examples/svelte/hydration/static/emblem-light.svg rename to examples/svelte/load-more-infinite-scroll/static/emblem-light.svg diff --git a/examples/svelte/load-more-infinite-scroll/svelte.config.js b/examples/svelte/load-more-infinite-scroll/svelte.config.js index 49c64ac5bf..05e80f6c7d 100644 --- a/examples/svelte/load-more-infinite-scroll/svelte.config.js +++ b/examples/svelte/load-more-infinite-scroll/svelte.config.js @@ -1,7 +1,15 @@ -import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' +import adapter from '@sveltejs/adapter-auto'; +import { vitePreprocess } from '@sveltejs/kit/vite'; -export default { - // Consult https://github.com/sveltejs/svelte-preprocess +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://kit.svelte.dev/docs/integrations#preprocessors // for more information about preprocessors - preprocess: vitePreprocess() -} + preprocess: vitePreprocess(), + + kit: { + adapter: adapter() + } +}; + +export default config; diff --git a/examples/svelte/load-more-infinite-scroll/tsconfig.json b/examples/svelte/load-more-infinite-scroll/tsconfig.json index d38303196a..794b95b642 100644 --- a/examples/svelte/load-more-infinite-scroll/tsconfig.json +++ b/examples/svelte/load-more-infinite-scroll/tsconfig.json @@ -1,21 +1,17 @@ { - "extends": "@tsconfig/svelte/tsconfig.json", + "extends": "./.svelte-kit/tsconfig.json", "compilerOptions": { - "target": "ESNext", - "useDefineForClassFields": true, - "module": "ESNext", - "resolveJsonModule": true, - "baseUrl": ".", - /** - * Typecheck JS in `.svelte` and `.js` files by default. - * Disable checkJs if you'd like to use dynamic types in JS. - * Note that setting allowJs false does not prevent the use - * of JS in `.svelte` files. - */ "allowJs": true, "checkJs": true, - "isolatedModules": true - }, - "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], - "references": [{ "path": "./tsconfig.node.json" }] + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true + } + // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in } diff --git a/examples/svelte/load-more-infinite-scroll/tsconfig.node.json b/examples/svelte/load-more-infinite-scroll/tsconfig.node.json deleted file mode 100644 index 65dbdb96ae..0000000000 --- a/examples/svelte/load-more-infinite-scroll/tsconfig.node.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "module": "ESNext", - "moduleResolution": "Node" - }, - "include": ["vite.config.ts"] -} diff --git a/examples/svelte/load-more-infinite-scroll/vite.config.ts b/examples/svelte/load-more-infinite-scroll/vite.config.ts index 401b4d4bd6..f2eb6d93cf 100644 --- a/examples/svelte/load-more-infinite-scroll/vite.config.ts +++ b/examples/svelte/load-more-infinite-scroll/vite.config.ts @@ -1,7 +1,8 @@ -import { defineConfig } from 'vite' -import { svelte } from '@sveltejs/vite-plugin-svelte' +import { sveltekit } from '@sveltejs/kit/vite'; +import type { UserConfig } from 'vite'; -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [svelte()] -}) +const config: UserConfig = { + plugins: [sveltekit()] +}; + +export default config; diff --git a/examples/svelte/optimistic-updates-typescript/package.json b/examples/svelte/optimistic-updates-typescript/package.json index 85c895df82..4ace661ad7 100644 --- a/examples/svelte/optimistic-updates-typescript/package.json +++ b/examples/svelte/optimistic-updates-typescript/package.json @@ -1,7 +1,8 @@ { "name": "@tanstack/query-example-svelte-optimistic-updates-typescript", - "version": "0.0.1", "private": true, + "version": "0.0.1", + "type": "module", "scripts": { "dev": "vite dev", "build": "vite build", @@ -9,7 +10,7 @@ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json" }, "dependencies": { - "@tanstack/svelte-query": "^4.12.0" + "@tanstack/svelte-query": "^4.20.0" }, "devDependencies": { "@sveltejs/adapter-auto": "^1.0.0", @@ -19,6 +20,5 @@ "tslib": "^2.4.1", "typescript": "^4.7.4", "vite": "^4.0.0" - }, - "type": "module" + } } diff --git a/examples/svelte/optimistic-updates-typescript/src/routes/+layout.svelte b/examples/svelte/optimistic-updates-typescript/src/routes/+layout.svelte index 26fb7c0a93..8c686d17ed 100644 --- a/examples/svelte/optimistic-updates-typescript/src/routes/+layout.svelte +++ b/examples/svelte/optimistic-updates-typescript/src/routes/+layout.svelte @@ -1,8 +1,15 @@ diff --git a/examples/svelte/optimistic-updates-typescript/src/routes/+layout.ts b/examples/svelte/optimistic-updates-typescript/src/routes/+layout.ts deleted file mode 100644 index 62ad4e4f47..0000000000 --- a/examples/svelte/optimistic-updates-typescript/src/routes/+layout.ts +++ /dev/null @@ -1 +0,0 @@ -export const ssr = false diff --git a/examples/svelte/playground/package.json b/examples/svelte/playground/package.json index 125de2873b..e34b0c2d37 100644 --- a/examples/svelte/playground/package.json +++ b/examples/svelte/playground/package.json @@ -10,7 +10,7 @@ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json" }, "dependencies": { - "@tanstack/svelte-query": "^4.12.0" + "@tanstack/svelte-query": "^4.20.0" }, "devDependencies": { "@sveltejs/adapter-auto": "^1.0.0", diff --git a/examples/svelte/playground/src/routes/+layout.svelte b/examples/svelte/playground/src/routes/+layout.svelte index fffc9a57be..8219a09ca9 100644 --- a/examples/svelte/playground/src/routes/+layout.svelte +++ b/examples/svelte/playground/src/routes/+layout.svelte @@ -1,8 +1,15 @@ diff --git a/examples/svelte/playground/src/routes/+layout.ts b/examples/svelte/playground/src/routes/+layout.ts deleted file mode 100644 index 62ad4e4f47..0000000000 --- a/examples/svelte/playground/src/routes/+layout.ts +++ /dev/null @@ -1 +0,0 @@ -export const ssr = false diff --git a/examples/svelte/simple/package.json b/examples/svelte/simple/package.json index 19d0ac364f..c28f0ff202 100644 --- a/examples/svelte/simple/package.json +++ b/examples/svelte/simple/package.json @@ -1,7 +1,7 @@ { "name": "@tanstack/query-example-svelte-simple", "private": true, - "version": "0.0.0", + "version": "0.0.1", "type": "module", "scripts": { "dev": "vite", @@ -10,7 +10,7 @@ "check": "svelte-check --tsconfig ./tsconfig.json" }, "dependencies": { - "@tanstack/svelte-query": "^4.12.0" + "@tanstack/svelte-query": "^4.20.0" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^2.0.2", diff --git a/examples/svelte/hydration/.gitignore b/examples/svelte/ssr/.gitignore similarity index 100% rename from examples/svelte/hydration/.gitignore rename to examples/svelte/ssr/.gitignore diff --git a/examples/svelte/hydration/README.md b/examples/svelte/ssr/README.md similarity index 100% rename from examples/svelte/hydration/README.md rename to examples/svelte/ssr/README.md diff --git a/examples/svelte/hydration/package.json b/examples/svelte/ssr/package.json similarity index 79% rename from examples/svelte/hydration/package.json rename to examples/svelte/ssr/package.json index 9003457846..80dbca3531 100644 --- a/examples/svelte/hydration/package.json +++ b/examples/svelte/ssr/package.json @@ -1,7 +1,8 @@ { - "name": "@tanstack/query-example-svelte-hydration", - "version": "0.0.1", + "name": "@tanstack/query-example-svelte-ssr", "private": true, + "version": "0.0.1", + "type": "module", "scripts": { "dev": "vite dev", "build": "vite build", @@ -9,7 +10,7 @@ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json" }, "dependencies": { - "@tanstack/svelte-query": "^4.12.0" + "@tanstack/svelte-query": "^4.20.0" }, "devDependencies": { "@sveltejs/adapter-auto": "^1.0.0", @@ -19,6 +20,5 @@ "tslib": "^2.4.1", "typescript": "^4.7.4", "vite": "^4.0.0" - }, - "type": "module" + } } diff --git a/examples/svelte/hydration/src/app.css b/examples/svelte/ssr/src/app.css similarity index 94% rename from examples/svelte/hydration/src/app.css rename to examples/svelte/ssr/src/app.css index c57658b1ef..d301f1b2a3 100644 --- a/examples/svelte/hydration/src/app.css +++ b/examples/svelte/ssr/src/app.css @@ -48,7 +48,7 @@ main { text-align: center; } -button { +.button { border-radius: 8px; border: 1px solid transparent; padding: 0.6em 1.2em; @@ -59,11 +59,11 @@ button { cursor: pointer; transition: border-color 0.25s; } -button:hover { +.button:hover { border-color: #646cff; } -button:focus, -button:focus-visible { +.button:focus, +.button:focus-visible { outline: 4px auto -webkit-focus-ring-color; } @@ -75,7 +75,7 @@ button:focus-visible { a:hover { color: #747bff; } - button { + .button { background-color: #f9f9f9; } } diff --git a/examples/svelte/ssr/src/app.d.ts b/examples/svelte/ssr/src/app.d.ts new file mode 100644 index 0000000000..3e4ed2057b --- /dev/null +++ b/examples/svelte/ssr/src/app.d.ts @@ -0,0 +1,9 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +// and what to do when importing types +declare namespace App { + // interface Locals {} + // interface PageData {} + // interface Error {} + // interface Platform {} +} diff --git a/examples/svelte/ssr/src/app.html b/examples/svelte/ssr/src/app.html new file mode 100644 index 0000000000..bf205c1085 --- /dev/null +++ b/examples/svelte/ssr/src/app.html @@ -0,0 +1,11 @@ + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/examples/svelte/hydration/src/lib/Post.svelte b/examples/svelte/ssr/src/lib/Post.svelte similarity index 68% rename from examples/svelte/hydration/src/lib/Post.svelte rename to examples/svelte/ssr/src/lib/Post.svelte index 1c13cf4be3..87b0f3234d 100644 --- a/examples/svelte/hydration/src/lib/Post.svelte +++ b/examples/svelte/ssr/src/lib/Post.svelte @@ -1,22 +1,19 @@
- + Back
{#if !postId || $post.isLoading} Loading... diff --git a/examples/svelte/hydration/src/lib/Posts.svelte b/examples/svelte/ssr/src/lib/Posts.svelte similarity index 88% rename from examples/svelte/hydration/src/lib/Posts.svelte rename to examples/svelte/ssr/src/lib/Posts.svelte index 0d3d63dad5..83b4112f66 100644 --- a/examples/svelte/hydration/src/lib/Posts.svelte +++ b/examples/svelte/ssr/src/lib/Posts.svelte @@ -1,11 +1,11 @@ + + +
+ +
+
diff --git a/examples/svelte/ssr/src/routes/+layout.ts b/examples/svelte/ssr/src/routes/+layout.ts new file mode 100644 index 0000000000..53b5e7ec76 --- /dev/null +++ b/examples/svelte/ssr/src/routes/+layout.ts @@ -0,0 +1,15 @@ +import { browser } from '$app/environment' +import { QueryClient } from '@tanstack/svelte-query' +import type { LayoutLoad } from './$types' + +export const load: LayoutLoad = async () => { + const queryClient = new QueryClient({ + defaultOptions: { + queries: { + enabled: browser, + }, + }, + }) + + return { queryClient } +} diff --git a/examples/svelte/ssr/src/routes/+page.svelte b/examples/svelte/ssr/src/routes/+page.svelte new file mode 100644 index 0000000000..dc95af5a51 --- /dev/null +++ b/examples/svelte/ssr/src/routes/+page.svelte @@ -0,0 +1,6 @@ + + +

Basic Query with SSR

+ diff --git a/examples/svelte/ssr/src/routes/+page.ts b/examples/svelte/ssr/src/routes/+page.ts new file mode 100644 index 0000000000..021b90ca9f --- /dev/null +++ b/examples/svelte/ssr/src/routes/+page.ts @@ -0,0 +1,11 @@ +import { getPosts } from '$lib/data' +import type { PageLoad } from './$types' + +export const load: PageLoad = async ({ parent }) => { + const { queryClient } = await parent() + + await queryClient.prefetchQuery({ + queryKey: ['posts', 10], + queryFn: () => getPosts(10), + }) +} diff --git a/examples/svelte/ssr/src/routes/[postId]/+page.svelte b/examples/svelte/ssr/src/routes/[postId]/+page.svelte new file mode 100644 index 0000000000..b68acc0bc0 --- /dev/null +++ b/examples/svelte/ssr/src/routes/[postId]/+page.svelte @@ -0,0 +1,8 @@ + + + diff --git a/examples/svelte/ssr/src/routes/[postId]/+page.ts b/examples/svelte/ssr/src/routes/[postId]/+page.ts new file mode 100644 index 0000000000..b30a7de223 --- /dev/null +++ b/examples/svelte/ssr/src/routes/[postId]/+page.ts @@ -0,0 +1,15 @@ +import { getPostById } from '$lib/data' +import type { PageLoad } from './$types' + +export const load: PageLoad = async ({ parent, params }) => { + const { queryClient } = await parent() + + const postId = parseInt(params.postId) + + await queryClient.prefetchQuery({ + queryKey: ['post', postId], + queryFn: () => getPostById(postId), + }) + + return { postId } +} diff --git a/examples/svelte/load-more-infinite-scroll/public/emblem-light.svg b/examples/svelte/ssr/static/emblem-light.svg similarity index 100% rename from examples/svelte/load-more-infinite-scroll/public/emblem-light.svg rename to examples/svelte/ssr/static/emblem-light.svg diff --git a/examples/svelte/hydration/svelte.config.js b/examples/svelte/ssr/svelte.config.js similarity index 100% rename from examples/svelte/hydration/svelte.config.js rename to examples/svelte/ssr/svelte.config.js diff --git a/examples/svelte/hydration/tsconfig.json b/examples/svelte/ssr/tsconfig.json similarity index 100% rename from examples/svelte/hydration/tsconfig.json rename to examples/svelte/ssr/tsconfig.json diff --git a/examples/svelte/hydration/vite.config.ts b/examples/svelte/ssr/vite.config.ts similarity index 100% rename from examples/svelte/hydration/vite.config.ts rename to examples/svelte/ssr/vite.config.ts diff --git a/examples/svelte/star-wars/package.json b/examples/svelte/star-wars/package.json index 9bf410b1c6..22afddea1d 100644 --- a/examples/svelte/star-wars/package.json +++ b/examples/svelte/star-wars/package.json @@ -10,7 +10,7 @@ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json" }, "dependencies": { - "@tanstack/svelte-query": "^4.12.0" + "@tanstack/svelte-query": "^4.20.0" }, "devDependencies": { "@sveltejs/adapter-auto": "^1.0.0", diff --git a/examples/svelte/star-wars/src/routes/+layout.svelte b/examples/svelte/star-wars/src/routes/+layout.svelte index 8c5c4a6ef7..36d59c23a8 100644 --- a/examples/svelte/star-wars/src/routes/+layout.svelte +++ b/examples/svelte/star-wars/src/routes/+layout.svelte @@ -1,8 +1,15 @@ @@ -13,9 +20,9 @@ diff --git a/examples/svelte/star-wars/src/routes/+layout.ts b/examples/svelte/star-wars/src/routes/+layout.ts deleted file mode 100644 index 62ad4e4f47..0000000000 --- a/examples/svelte/star-wars/src/routes/+layout.ts +++ /dev/null @@ -1 +0,0 @@ -export const ssr = false diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 624b63853b..b2a99447bc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -644,7 +644,7 @@ importers: specifiers: '@sveltejs/adapter-auto': ^1.0.0 '@sveltejs/kit': ^1.0.0 - '@tanstack/svelte-query': ^4.12.0 + '@tanstack/svelte-query': ^4.20.0 svelte: ^3.54.0 svelte-check: ^2.9.2 tslib: ^2.4.1 @@ -663,9 +663,9 @@ importers: examples/svelte/basic: specifiers: - '@sveltejs/vite-plugin-svelte': ^2.0.2 - '@tanstack/svelte-query': ^4.12.0 - '@tsconfig/svelte': ^3.0.0 + '@sveltejs/adapter-auto': ^1.0.0 + '@sveltejs/kit': ^1.0.0 + '@tanstack/svelte-query': ^4.20.0 svelte: ^3.54.0 svelte-check: ^2.9.2 tslib: ^2.4.1 @@ -674,19 +674,19 @@ importers: dependencies: '@tanstack/svelte-query': link:../../../packages/svelte-query devDependencies: - '@sveltejs/vite-plugin-svelte': 2.0.2_svelte@3.55.0+vite@4.0.4 - '@tsconfig/svelte': 3.0.0 + '@sveltejs/adapter-auto': 1.0.0_@sveltejs+kit@1.0.7 + '@sveltejs/kit': 1.0.7_svelte@3.55.0+vite@4.0.4 svelte: 3.55.0 svelte-check: 2.10.3_svelte@3.55.0 tslib: 2.4.1 typescript: 4.8.4 vite: 4.0.4 - examples/svelte/hydration: + examples/svelte/load-more-infinite-scroll: specifiers: '@sveltejs/adapter-auto': ^1.0.0 '@sveltejs/kit': ^1.0.0 - '@tanstack/svelte-query': ^4.12.0 + '@tanstack/svelte-query': ^4.20.0 svelte: ^3.54.0 svelte-check: ^2.9.2 tslib: ^2.4.1 @@ -703,11 +703,11 @@ importers: typescript: 4.8.4 vite: 4.0.4 - examples/svelte/load-more-infinite-scroll: + examples/svelte/optimistic-updates-typescript: specifiers: - '@sveltejs/vite-plugin-svelte': ^2.0.2 - '@tanstack/svelte-query': ^4.12.0 - '@tsconfig/svelte': ^3.0.0 + '@sveltejs/adapter-auto': ^1.0.0 + '@sveltejs/kit': ^1.0.0 + '@tanstack/svelte-query': ^4.20.0 svelte: ^3.54.0 svelte-check: ^2.9.2 tslib: ^2.4.1 @@ -716,19 +716,19 @@ importers: dependencies: '@tanstack/svelte-query': link:../../../packages/svelte-query devDependencies: - '@sveltejs/vite-plugin-svelte': 2.0.2_svelte@3.55.0+vite@4.0.4 - '@tsconfig/svelte': 3.0.0 + '@sveltejs/adapter-auto': 1.0.0_@sveltejs+kit@1.0.7 + '@sveltejs/kit': 1.0.7_svelte@3.55.0+vite@4.0.4 svelte: 3.55.0 svelte-check: 2.10.3_svelte@3.55.0 tslib: 2.4.1 typescript: 4.8.4 vite: 4.0.4 - examples/svelte/optimistic-updates-typescript: + examples/svelte/playground: specifiers: '@sveltejs/adapter-auto': ^1.0.0 '@sveltejs/kit': ^1.0.0 - '@tanstack/svelte-query': ^4.12.0 + '@tanstack/svelte-query': ^4.20.0 svelte: ^3.54.0 svelte-check: ^2.9.2 tslib: ^2.4.1 @@ -745,11 +745,11 @@ importers: typescript: 4.8.4 vite: 4.0.4 - examples/svelte/playground: + examples/svelte/simple: specifiers: - '@sveltejs/adapter-auto': ^1.0.0 - '@sveltejs/kit': ^1.0.0 - '@tanstack/svelte-query': ^4.12.0 + '@sveltejs/vite-plugin-svelte': ^2.0.2 + '@tanstack/svelte-query': ^4.20.0 + '@tsconfig/svelte': ^3.0.0 svelte: ^3.54.0 svelte-check: ^2.9.2 tslib: ^2.4.1 @@ -758,19 +758,19 @@ importers: dependencies: '@tanstack/svelte-query': link:../../../packages/svelte-query devDependencies: - '@sveltejs/adapter-auto': 1.0.0_@sveltejs+kit@1.0.7 - '@sveltejs/kit': 1.0.7_svelte@3.55.0+vite@4.0.4 + '@sveltejs/vite-plugin-svelte': 2.0.2_svelte@3.55.0+vite@4.0.4 + '@tsconfig/svelte': 3.0.0 svelte: 3.55.0 svelte-check: 2.10.3_svelte@3.55.0 tslib: 2.4.1 typescript: 4.8.4 vite: 4.0.4 - examples/svelte/simple: + examples/svelte/ssr: specifiers: - '@sveltejs/vite-plugin-svelte': ^2.0.2 - '@tanstack/svelte-query': ^4.12.0 - '@tsconfig/svelte': ^3.0.0 + '@sveltejs/adapter-auto': ^1.0.0 + '@sveltejs/kit': ^1.0.0 + '@tanstack/svelte-query': ^4.20.0 svelte: ^3.54.0 svelte-check: ^2.9.2 tslib: ^2.4.1 @@ -779,8 +779,8 @@ importers: dependencies: '@tanstack/svelte-query': link:../../../packages/svelte-query devDependencies: - '@sveltejs/vite-plugin-svelte': 2.0.2_svelte@3.55.0+vite@4.0.4 - '@tsconfig/svelte': 3.0.0 + '@sveltejs/adapter-auto': 1.0.0_@sveltejs+kit@1.0.7 + '@sveltejs/kit': 1.0.7_svelte@3.55.0+vite@4.0.4 svelte: 3.55.0 svelte-check: 2.10.3_svelte@3.55.0 tslib: 2.4.1 @@ -791,7 +791,7 @@ importers: specifiers: '@sveltejs/adapter-auto': ^1.0.0 '@sveltejs/kit': ^1.0.0 - '@tanstack/svelte-query': ^4.12.0 + '@tanstack/svelte-query': ^4.20.0 autoprefixer: ^10.4.13 postcss: ^8.4.20 svelte: ^3.54.0 From e33bda3131442f34577f13c73f3c6e890b504a62 Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Sat, 14 Jan 2023 00:18:36 +1100 Subject: [PATCH 18/37] chore: Add sandbox.config.json (#4812) --- examples/svelte/auto-refetching/sandbox.config.json | 5 +++++ examples/svelte/basic/sandbox.config.json | 5 +++++ .../svelte/load-more-infinite-scroll/sandbox.config.json | 5 +++++ .../svelte/optimistic-updates-typescript/sandbox.config.json | 5 +++++ examples/svelte/playground/sandbox.config.json | 5 +++++ examples/svelte/simple/sandbox.config.json | 5 +++++ examples/svelte/ssr/sandbox.config.json | 5 +++++ examples/svelte/star-wars/sandbox.config.json | 5 +++++ 8 files changed, 40 insertions(+) create mode 100644 examples/svelte/auto-refetching/sandbox.config.json create mode 100644 examples/svelte/basic/sandbox.config.json create mode 100644 examples/svelte/load-more-infinite-scroll/sandbox.config.json create mode 100644 examples/svelte/optimistic-updates-typescript/sandbox.config.json create mode 100644 examples/svelte/playground/sandbox.config.json create mode 100644 examples/svelte/simple/sandbox.config.json create mode 100644 examples/svelte/ssr/sandbox.config.json create mode 100644 examples/svelte/star-wars/sandbox.config.json diff --git a/examples/svelte/auto-refetching/sandbox.config.json b/examples/svelte/auto-refetching/sandbox.config.json new file mode 100644 index 0000000000..0da04c0cad --- /dev/null +++ b/examples/svelte/auto-refetching/sandbox.config.json @@ -0,0 +1,5 @@ +{ + "container": { + "node": "16" + } +} diff --git a/examples/svelte/basic/sandbox.config.json b/examples/svelte/basic/sandbox.config.json new file mode 100644 index 0000000000..0da04c0cad --- /dev/null +++ b/examples/svelte/basic/sandbox.config.json @@ -0,0 +1,5 @@ +{ + "container": { + "node": "16" + } +} diff --git a/examples/svelte/load-more-infinite-scroll/sandbox.config.json b/examples/svelte/load-more-infinite-scroll/sandbox.config.json new file mode 100644 index 0000000000..0da04c0cad --- /dev/null +++ b/examples/svelte/load-more-infinite-scroll/sandbox.config.json @@ -0,0 +1,5 @@ +{ + "container": { + "node": "16" + } +} diff --git a/examples/svelte/optimistic-updates-typescript/sandbox.config.json b/examples/svelte/optimistic-updates-typescript/sandbox.config.json new file mode 100644 index 0000000000..0da04c0cad --- /dev/null +++ b/examples/svelte/optimistic-updates-typescript/sandbox.config.json @@ -0,0 +1,5 @@ +{ + "container": { + "node": "16" + } +} diff --git a/examples/svelte/playground/sandbox.config.json b/examples/svelte/playground/sandbox.config.json new file mode 100644 index 0000000000..0da04c0cad --- /dev/null +++ b/examples/svelte/playground/sandbox.config.json @@ -0,0 +1,5 @@ +{ + "container": { + "node": "16" + } +} diff --git a/examples/svelte/simple/sandbox.config.json b/examples/svelte/simple/sandbox.config.json new file mode 100644 index 0000000000..0da04c0cad --- /dev/null +++ b/examples/svelte/simple/sandbox.config.json @@ -0,0 +1,5 @@ +{ + "container": { + "node": "16" + } +} diff --git a/examples/svelte/ssr/sandbox.config.json b/examples/svelte/ssr/sandbox.config.json new file mode 100644 index 0000000000..0da04c0cad --- /dev/null +++ b/examples/svelte/ssr/sandbox.config.json @@ -0,0 +1,5 @@ +{ + "container": { + "node": "16" + } +} diff --git a/examples/svelte/star-wars/sandbox.config.json b/examples/svelte/star-wars/sandbox.config.json new file mode 100644 index 0000000000..0da04c0cad --- /dev/null +++ b/examples/svelte/star-wars/sandbox.config.json @@ -0,0 +1,5 @@ +{ + "container": { + "node": "16" + } +} From 832d4fb0349b0fb29b1c49f25b9acb71ce42e301 Mon Sep 17 00:00:00 2001 From: Masaki Koyanagi Date: Fri, 13 Jan 2023 23:37:10 +0900 Subject: [PATCH 19/37] docs: fix typo (quey -> query) (#4813) --- docs/react/guides/caching.md | 4 ++-- docs/react/guides/placeholder-query-data.md | 2 +- packages/vue-query/README.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/react/guides/caching.md b/docs/react/guides/caching.md index bbaf0ee2aa..1307f1ee5d 100644 --- a/docs/react/guides/caching.md +++ b/docs/react/guides/caching.md @@ -27,7 +27,7 @@ Let's assume we are using the default `cacheTime` of **5 minutes** and the defau - When the request completes successfully, the cache's data under the `['todos']` key is updated with the new data, and both instances are updated with the new data. - Both instances of the `useQuery({ queryKey: ['todos'], queryFn: fetchTodos })` query are unmounted and no longer in use. - Since there are no more active instances of this query, a cache timeout is set using `cacheTime` to delete and garbage collect the query (defaults to **5 minutes**). -- Before the cache timeout has completed, another instance of `useQuery({ queryKey: ['todos'], queyFn: fetchTodos })` mounts. The query immediately returns the available cached data while the `fetchTodos` function is being run in the background. When it completes successfully, it will populate the cache with fresh data. +- Before the cache timeout has completed, another instance of `useQuery({ queryKey: ['todos'], queryFn: fetchTodos })` mounts. The query immediately returns the available cached data while the `fetchTodos` function is being run in the background. When it completes successfully, it will populate the cache with fresh data. - The final instance of `useQuery({ queryKey: ['todos'], queryFn: fetchTodos })` unmounts. -- No more instances of `useQuery({ queyKey: ['todos'], queryFn: fetchTodos })` appear within **5 minutes**. +- No more instances of `useQuery({ queryKey: ['todos'], queryFn: fetchTodos })` appear within **5 minutes**. - The cached data under the `['todos']` key is deleted and garbage collected. diff --git a/docs/react/guides/placeholder-query-data.md b/docs/react/guides/placeholder-query-data.md index d847aa129b..a1105677ef 100644 --- a/docs/react/guides/placeholder-query-data.md +++ b/docs/react/guides/placeholder-query-data.md @@ -44,7 +44,7 @@ If the process for accessing a query's placeholder data is intensive or just not function Todos() { const placeholderData = useMemo(() => generateFakeTodos(), []) const result = useQuery({ - queyKey: ['todos'], + queryKey: ['todos'], queryFn: () => fetch('/todos'), placeholderData, }) diff --git a/packages/vue-query/README.md b/packages/vue-query/README.md index a882b1c09a..2125d07623 100644 --- a/packages/vue-query/README.md +++ b/packages/vue-query/README.md @@ -79,5 +79,5 @@ Visit https://tanstack.com/query/v4/docs/adapters/vue-query const id = ref(1); const enabled = ref(false); - const query = useQuery({ queyKey: ["todos", id], queryFn: () => getTodos(id), enabled }); + const query = useQuery({ queryKey: ["todos", id], queryFn: () => getTodos(id), enabled }); ``` From 86161ca6ec7b29f71576b555206aca04831499e6 Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Sun, 15 Jan 2023 03:25:20 +1100 Subject: [PATCH 20/37] docs(svelte-query): Add recommended defaults to prefetchQuery setup (#4815) * Add recommended defaults to prefetch example * Move SSR docs up in sidebar --- docs/config.json | 8 ++++---- docs/svelte/overview.md | 2 +- docs/svelte/ssr.md | 14 ++++++++++++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/docs/config.json b/docs/config.json index 95329df12e..8474602959 100644 --- a/docs/config.json +++ b/docs/config.json @@ -695,13 +695,13 @@ "label": "Installation", "to": "svelte/installation" }, - { - "label": "Reactivity", - "to": "svelte/reactivity" - }, { "label": "SSR & SvelteKit", "to": "svelte/ssr" + }, + { + "label": "Reactivity", + "to": "svelte/reactivity" } ] }, diff --git a/docs/svelte/overview.md b/docs/svelte/overview.md index 79e40a8c53..14fb67c81a 100644 --- a/docs/svelte/overview.md +++ b/docs/svelte/overview.md @@ -11,7 +11,7 @@ Include the QueryClientProvider near the root of your project: ```markdown - + diff --git a/packages/svelte-query/src/__tests__/createMutation.test.ts b/packages/svelte-query/src/__tests__/createMutation.test.ts index a129e5784e..bfa64be0b8 100644 --- a/packages/svelte-query/src/__tests__/createMutation.test.ts +++ b/packages/svelte-query/src/__tests__/createMutation.test.ts @@ -5,11 +5,11 @@ import { sleep } from './utils' describe('createMutation', () => { it('Call mutate and check function runs', async () => { - const queryFn = vi.fn() + const mutationFn = vi.fn() render(CreateMutation, { props: { - queryFn, + mutationFn, }, }) @@ -17,6 +17,6 @@ describe('createMutation', () => { await sleep(200) - expect(queryFn).toHaveBeenCalledTimes(1) + expect(mutationFn).toHaveBeenCalledTimes(1) }) }) diff --git a/packages/svelte-query/src/createMutation.ts b/packages/svelte-query/src/createMutation.ts index 532bc50722..c0b2b95808 100644 --- a/packages/svelte-query/src/createMutation.ts +++ b/packages/svelte-query/src/createMutation.ts @@ -7,7 +7,7 @@ import { parseMutationArgs, } from '@tanstack/query-core' import type { - UseMutateFunction, + CreateMutateFunction, CreateMutationOptions, CreateMutationResult, } from './types' @@ -16,7 +16,7 @@ import { useQueryClient } from './useQueryClient' export function createMutation< TData = unknown, TError = unknown, - TVariables = unknown, + TVariables = void, TContext = unknown, >( options: CreateMutationOptions, @@ -25,7 +25,7 @@ export function createMutation< export function createMutation< TData = unknown, TError = unknown, - TVariables = unknown, + TVariables = void, TContext = unknown, >( mutationFn: MutationFunction, @@ -38,7 +38,7 @@ export function createMutation< export function createMutation< TData = unknown, TError = unknown, - TVariables = unknown, + TVariables = void, TContext = unknown, >( mutationKey: MutationKey, @@ -51,7 +51,7 @@ export function createMutation< export function createMutation< TData = unknown, TError = unknown, - TVariables = unknown, + TVariables = void, TContext = unknown, >( mutationKey: MutationKey, @@ -65,7 +65,7 @@ export function createMutation< export function createMutation< TData = unknown, TError = unknown, - TVariables = unknown, + TVariables = void, TContext = unknown, >( arg1: @@ -83,7 +83,7 @@ export function createMutation< queryClient, options, ) - let mutate: UseMutateFunction + let mutate: CreateMutateFunction readable(observer).subscribe(($observer) => { observer = $observer diff --git a/packages/svelte-query/src/types.ts b/packages/svelte-query/src/types.ts index 76760dfc8d..853f6c464b 100644 --- a/packages/svelte-query/src/types.ts +++ b/packages/svelte-query/src/types.ts @@ -87,7 +87,7 @@ export interface CreateMutationOptions< '_defaulted' | 'variables' > {} -export type UseMutateFunction< +export type CreateMutateFunction< TData = unknown, TError = unknown, TVariables = void, @@ -96,22 +96,24 @@ export type UseMutateFunction< ...args: Parameters> ) => void -export type UseMutateAsyncFunction< +export type CreateMutateAsyncFunction< TData = unknown, TError = unknown, TVariables = void, TContext = unknown, > = MutateFunction -export type UseBaseMutationResult< +export type CreateBaseMutationResult< TData = unknown, TError = unknown, TVariables = unknown, TContext = unknown, > = Override< MutationObserverResult, - { mutate: UseMutateFunction } -> & { mutateAsync: UseMutateAsyncFunction } + { mutate: CreateMutateFunction } +> & { + mutateAsync: CreateMutateAsyncFunction +} export interface CreateMutationResult< TData = unknown, @@ -119,7 +121,7 @@ export interface CreateMutationResult< TVariables = unknown, TContext = unknown, > extends Readable< - UseBaseMutationResult + CreateBaseMutationResult > {} type Override = { [K in keyof A]: K extends keyof B ? B[K] : A[K] } From bae03c00b44817bce1017f0ca7a1106799711594 Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Sat, 21 Jan 2023 14:59:00 +0000 Subject: [PATCH 27/37] release: v4.22.3 --- packages/react-query-devtools/package.json | 2 +- packages/react-query-persist-client/package.json | 2 +- packages/react-query/package.json | 2 +- packages/svelte-query/package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-query-devtools/package.json b/packages/react-query-devtools/package.json index f759ec382c..33e55d52f5 100644 --- a/packages/react-query-devtools/package.json +++ b/packages/react-query-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-query-devtools", - "version": "4.22.0", + "version": "4.22.3", "description": "Developer tools to interact with and visualize the TanStack/react-query cache", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/react-query-persist-client/package.json b/packages/react-query-persist-client/package.json index bae9ec47e6..5b8cfbbe5c 100644 --- a/packages/react-query-persist-client/package.json +++ b/packages/react-query-persist-client/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-query-persist-client", - "version": "4.22.0", + "version": "4.22.3", "description": "React bindings to work with persisters in TanStack/react-query", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/react-query/package.json b/packages/react-query/package.json index 1800d9d897..91c12cf1c0 100644 --- a/packages/react-query/package.json +++ b/packages/react-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-query", - "version": "4.22.0", + "version": "4.22.3", "description": "Hooks for managing, caching and syncing asynchronous and remote data in React", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/svelte-query/package.json b/packages/svelte-query/package.json index 03146a31ed..9ffe410364 100644 --- a/packages/svelte-query/package.json +++ b/packages/svelte-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/svelte-query", - "version": "4.22.2", + "version": "4.22.3", "description": "Primitives for managing, caching and syncing asynchronous and remote data in Svelte", "author": "Dre Johnson", "license": "MIT", From 901e826f394d185f2e7f7b9641c20ee77327bea1 Mon Sep 17 00:00:00 2001 From: Jan <39303600+janlat@users.noreply.github.com> Date: Sun, 22 Jan 2023 16:56:54 +0100 Subject: [PATCH 28/37] fix(core): do not call mutate callbacks if mutation started after unmount (#4848) * test: add mutation callback after unmount test * test: make test more resilient * fix(core): do not call mutate callbacks if mutation started after unmount * test: adapt tests to what we have in v5 - one test has been removed (because setState was removed entirely) - the second test has been re-written to not use internals anymore, and it works in v4 as well * fix(core): do not call mutate callbacks if mutation started after unmount by making sure the callbacks are only invoked if we have an active listener * chore: prettier again Co-authored-by: Dominik Dorfmeister --- packages/query-core/src/mutationObserver.ts | 2 +- .../query-core/src/tests/mutations.test.tsx | 67 ++++++++----------- .../src/__tests__/useMutation.test.tsx | 62 ++++++++++++++++- 3 files changed, 89 insertions(+), 42 deletions(-) diff --git a/packages/query-core/src/mutationObserver.ts b/packages/query-core/src/mutationObserver.ts index 20f7e62da2..af66852895 100644 --- a/packages/query-core/src/mutationObserver.ts +++ b/packages/query-core/src/mutationObserver.ts @@ -166,7 +166,7 @@ export class MutationObserver< private notify(options: NotifyOptions) { notifyManager.batch(() => { // First trigger the mutate callbacks - if (this.mutateOptions) { + if (this.mutateOptions && this.hasListeners()) { if (options.onSuccess) { this.mutateOptions.onSuccess?.( this.currentResult.data!, diff --git a/packages/query-core/src/tests/mutations.test.tsx b/packages/query-core/src/tests/mutations.test.tsx index 5eced09b45..ccb6ae2ad1 100644 --- a/packages/query-core/src/tests/mutations.test.tsx +++ b/packages/query-core/src/tests/mutations.test.tsx @@ -308,49 +308,24 @@ describe('mutations', () => { expect(onSettled).toHaveBeenCalled() }) - test('setState should update the mutation state', async () => { - const mutation = new MutationObserver(queryClient, { - mutationFn: async () => { - return 'update' - }, - onMutate: (text) => text, - }) - await mutation.mutate() - expect(mutation.getCurrentResult().data).toEqual('update') - - // Force setState usage - // because no use case has been found using mutation.setState - const currentMutation = mutation['currentMutation'] - currentMutation?.setState({ - context: undefined, - variables: undefined, - data: 'new', - error: undefined, - failureCount: 0, - failureReason: null, - isPaused: false, - status: 'success', - }) + test('addObserver should not add an existing observer', async () => { + const mutationCache = queryClient.getMutationCache() + const observer = new MutationObserver(queryClient, {}) + const currentMutation = mutationCache.build(queryClient, {}) - expect(mutation.getCurrentResult().data).toEqual('new') - }) + const fn = jest.fn() - test('addObserver should not add an existing observer', async () => { - const mutation = new MutationObserver(queryClient, { - mutationFn: async () => { - return 'update' - }, - onMutate: (text) => text, + const unsubscribe = mutationCache.subscribe((event) => { + fn(event.type) }) - await mutation.mutate() - // Force addObserver usage to add an existing observer - // because no use case has been found - const currentMutation = mutation['currentMutation']! - expect(currentMutation['observers'].length).toEqual(1) - currentMutation.addObserver(mutation) + currentMutation.addObserver(observer) + currentMutation.addObserver(observer) - expect(currentMutation['observers'].length).toEqual(1) + expect(fn).toHaveBeenCalledTimes(1) + expect(fn).toHaveBeenCalledWith('observerAdded') + + unsubscribe() }) test('mutate should throw an error if no mutationFn found', async () => { @@ -367,4 +342,20 @@ describe('mutations', () => { } expect(error).toEqual('No mutationFn found') }) + + test('mutate update the mutation state even without an active subscription', async () => { + const onSuccess = jest.fn() + const onSettled = jest.fn() + + const mutation = new MutationObserver(queryClient, { + mutationFn: async () => { + return 'update' + }, + }) + + await mutation.mutate(undefined, { onSuccess, onSettled }) + expect(mutation.getCurrentResult().data).toEqual('update') + expect(onSuccess).not.toHaveBeenCalled() + expect(onSettled).not.toHaveBeenCalled() + }) }) diff --git a/packages/react-query/src/__tests__/useMutation.test.tsx b/packages/react-query/src/__tests__/useMutation.test.tsx index fe626500ad..ff32046f0e 100644 --- a/packages/react-query/src/__tests__/useMutation.test.tsx +++ b/packages/react-query/src/__tests__/useMutation.test.tsx @@ -1044,7 +1044,7 @@ describe('useMutation', () => { ) }) - test('should go to error state if onSuccess callback errors', async () => { + it('should go to error state if onSuccess callback errors', async () => { const error = new Error('error from onSuccess') const onError = jest.fn() @@ -1079,7 +1079,7 @@ describe('useMutation', () => { expect(onError).toHaveBeenCalledWith(error, 'todo', undefined) }) - test('should go to error state if onError callback errors', async () => { + it('should go to error state if onError callback errors', async () => { const error = new Error('error from onError') const mutateFnError = new Error('mutateFnError') @@ -1115,7 +1115,7 @@ describe('useMutation', () => { await rendered.findByText('error: mutateFnError, status: error') }) - test('should go to error state if onSettled callback errors', async () => { + it('should go to error state if onSettled callback errors', async () => { const error = new Error('error from onSettled') const mutateFnError = new Error('mutateFnError') const onError = jest.fn() @@ -1154,4 +1154,60 @@ describe('useMutation', () => { expect(onError).toHaveBeenCalledWith(mutateFnError, 'todo', undefined) }) + + it('should not call mutate callbacks for mutations started after unmount', async () => { + const onSuccessMutate = jest.fn() + const onSuccessUseMutation = jest.fn() + const onSettledMutate = jest.fn() + const onSettledUseMutation = jest.fn() + + function Page() { + const [show, setShow] = React.useState(true) + return ( +
+ + {show && } +
+ ) + } + + function Component() { + const mutation = useMutation({ + mutationFn: async (text: string) => { + await sleep(10) + return text + }, + onSuccess: onSuccessUseMutation, + onSettled: onSettledUseMutation, + }) + + return ( +
+ +
+ ) + } + + const rendered = renderWithClient(queryClient, ) + + fireEvent.click(rendered.getByRole('button', { name: /mutate/i })) + fireEvent.click(rendered.getByRole('button', { name: /hide/i })) + + await waitFor(() => expect(onSuccessUseMutation).toHaveBeenCalledTimes(1)) + await waitFor(() => expect(onSettledUseMutation).toHaveBeenCalledTimes(1)) + + expect(onSuccessMutate).toHaveBeenCalledTimes(0) + expect(onSettledMutate).toHaveBeenCalledTimes(0) + }) }) From 81baae3088f3488d0c177beca48fdd643d191578 Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Sun, 22 Jan 2023 16:01:51 +0000 Subject: [PATCH 29/37] release: v4.22.4 --- packages/query-async-storage-persister/package.json | 2 +- packages/query-broadcast-client-experimental/package.json | 2 +- packages/query-core/package.json | 2 +- packages/query-persist-client-core/package.json | 2 +- packages/query-sync-storage-persister/package.json | 2 +- packages/react-query-devtools/package.json | 2 +- packages/react-query-persist-client/package.json | 2 +- packages/react-query/package.json | 2 +- packages/solid-query/package.json | 2 +- packages/svelte-query/package.json | 2 +- packages/vue-query/package.json | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/query-async-storage-persister/package.json b/packages/query-async-storage-persister/package.json index 3d73400c9e..d6dd8f520f 100644 --- a/packages/query-async-storage-persister/package.json +++ b/packages/query-async-storage-persister/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/query-async-storage-persister", - "version": "4.22.0", + "version": "4.22.4", "description": "A persister for asynchronous storages, to be used with TanStack/Query", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/query-broadcast-client-experimental/package.json b/packages/query-broadcast-client-experimental/package.json index bd47efd2aa..e2e079212d 100644 --- a/packages/query-broadcast-client-experimental/package.json +++ b/packages/query-broadcast-client-experimental/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/query-broadcast-client-experimental", - "version": "4.22.0", + "version": "4.22.4", "description": "An experimental plugin to for broadcasting the state of your queryClient between browser tabs/windows", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/query-core/package.json b/packages/query-core/package.json index 2b67a1b785..30dcf50de2 100644 --- a/packages/query-core/package.json +++ b/packages/query-core/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/query-core", - "version": "4.22.0", + "version": "4.22.4", "description": "The framework agnostic core that powers TanStack Query", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/query-persist-client-core/package.json b/packages/query-persist-client-core/package.json index 5ed7b5d158..997e989676 100644 --- a/packages/query-persist-client-core/package.json +++ b/packages/query-persist-client-core/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/query-persist-client-core", - "version": "4.22.0", + "version": "4.22.4", "description": "Set of utilities for interacting with persisters, which can save your queryClient for later use", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/query-sync-storage-persister/package.json b/packages/query-sync-storage-persister/package.json index be344884c5..ad2a80cacf 100644 --- a/packages/query-sync-storage-persister/package.json +++ b/packages/query-sync-storage-persister/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/query-sync-storage-persister", - "version": "4.22.0", + "version": "4.22.4", "description": "A persister for synchronous storages, to be used with TanStack/Query", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/react-query-devtools/package.json b/packages/react-query-devtools/package.json index 33e55d52f5..82cc8a8d05 100644 --- a/packages/react-query-devtools/package.json +++ b/packages/react-query-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-query-devtools", - "version": "4.22.3", + "version": "4.22.4", "description": "Developer tools to interact with and visualize the TanStack/react-query cache", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/react-query-persist-client/package.json b/packages/react-query-persist-client/package.json index 5b8cfbbe5c..3d67b22bc6 100644 --- a/packages/react-query-persist-client/package.json +++ b/packages/react-query-persist-client/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-query-persist-client", - "version": "4.22.3", + "version": "4.22.4", "description": "React bindings to work with persisters in TanStack/react-query", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/react-query/package.json b/packages/react-query/package.json index 91c12cf1c0..87353f7b05 100644 --- a/packages/react-query/package.json +++ b/packages/react-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-query", - "version": "4.22.3", + "version": "4.22.4", "description": "Hooks for managing, caching and syncing asynchronous and remote data in React", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/solid-query/package.json b/packages/solid-query/package.json index 29f1a5178e..61f6a6e41e 100644 --- a/packages/solid-query/package.json +++ b/packages/solid-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/solid-query", - "version": "4.22.0", + "version": "4.22.4", "description": "Primitives for managing, caching and syncing asynchronous and remote data in Solid", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/svelte-query/package.json b/packages/svelte-query/package.json index 9ffe410364..3b75811634 100644 --- a/packages/svelte-query/package.json +++ b/packages/svelte-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/svelte-query", - "version": "4.22.3", + "version": "4.22.4", "description": "Primitives for managing, caching and syncing asynchronous and remote data in Svelte", "author": "Dre Johnson", "license": "MIT", diff --git a/packages/vue-query/package.json b/packages/vue-query/package.json index 15fb0f41e4..40950f13c3 100644 --- a/packages/vue-query/package.json +++ b/packages/vue-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/vue-query", - "version": "4.22.0", + "version": "4.22.4", "description": "Hooks for managing, caching and syncing asynchronous and remote data in Vue", "author": "Damian Osipiuk", "license": "MIT", From 4ac7c1a8b61faedd4e9f5a999eef9becc9ed65d3 Mon Sep 17 00:00:00 2001 From: Qz <38932402+QzCurious@users.noreply.github.com> Date: Mon, 23 Jan 2023 14:57:19 +0800 Subject: [PATCH 30/37] docs(useMutation): correct docs for mutate function callbacks (#4601) * docs(useMutation): correct docs for mutate function callbacks * docs: fix merge conflicts Co-authored-by: Dominik Dorfmeister --- docs/react/guides/mutations.md | 2 +- docs/react/reference/useMutation.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/react/guides/mutations.md b/docs/react/guides/mutations.md index 790396deb5..478df96092 100644 --- a/docs/react/guides/mutations.md +++ b/docs/react/guides/mutations.md @@ -182,7 +182,7 @@ useMutation({ [//]: # 'Example5' -You might find that you want to **trigger additional callbacks** beyond the ones defined on `useMutation` when calling `mutate`. This can be used to trigger component-specific side effects. To do that, you can provide any of the same callback options to the `mutate` function after your mutation variable. Supported overrides include: `onSuccess`, `onError` and `onSettled`. Please keep in mind that those additional callbacks won't run if your component unmounts _before_ the mutation finishes. +You might find that you want to **trigger additional callbacks** beyond the ones defined on `useMutation` when calling `mutate`. This can be used to trigger component-specific side effects. To do that, you can provide any of the same callback options to the `mutate` function after your mutation variable. Supported options include: `onSuccess`, `onError` and `onSettled`. Please keep in mind that those additional callbacks won't run if your component unmounts _before_ the mutation finishes. [//]: # 'Example6' diff --git a/docs/react/reference/useMutation.md b/docs/react/reference/useMutation.md index 36ee1c6652..cf7601f002 100644 --- a/docs/react/reference/useMutation.md +++ b/docs/react/reference/useMutation.md @@ -96,7 +96,7 @@ mutate(variables, { **Returns** - `mutate: (variables: TVariables, { onSuccess, onSettled, onError }) => void` - - The mutation function you can call with variables to trigger the mutation and optionally override options passed to `useMutation`. + - The mutation function you can call with variables to trigger the mutation and optionally hooks on additional callback options. - `variables: TVariables` - Optional - The variables object to pass to the `mutationFn`. From 69a7d72d34b06925d41ec3cb487a21330118570c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Kuijper?= <31251240+Joehoel@users.noreply.github.com> Date: Mon, 23 Jan 2023 13:08:09 +0100 Subject: [PATCH 31/37] docs: add QueryClient import (#4856) --- docs/react/plugins/createAsyncStoragePersister.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/react/plugins/createAsyncStoragePersister.md b/docs/react/plugins/createAsyncStoragePersister.md index d2107bce66..0fce022259 100644 --- a/docs/react/plugins/createAsyncStoragePersister.md +++ b/docs/react/plugins/createAsyncStoragePersister.md @@ -27,6 +27,7 @@ yarn add @tanstack/query-async-storage-persister @tanstack/react-query-persist-c ```tsx import AsyncStorage from '@react-native-async-storage/async-storage' +import { QueryClient } from '@tanstack/react-query' import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client' import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister' From ea673770c00c0aa94428126dc7a2d358cba911de Mon Sep 17 00:00:00 2001 From: Dominik Dorfmeister Date: Mon, 23 Jan 2023 16:31:16 +0100 Subject: [PATCH 32/37] docs: add readme.md to react adapter --- packages/react-query/README.md | 51 ++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 packages/react-query/README.md diff --git a/packages/react-query/README.md b/packages/react-query/README.md new file mode 100644 index 0000000000..f98d650d8b --- /dev/null +++ b/packages/react-query/README.md @@ -0,0 +1,51 @@ + + +![TanStack Query Header](https://github.com/TanStack/query/raw/beta/media/repo-header.png) + +Hooks for fetching, caching and updating asynchronous data in React + + + #TanStack + + + + + + + + + + semantic-release + + Join the discussion on Github +Best of JS + + + + + Gitpod Ready-to-Code + + +Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [TanStack Table](https://github.com/TanStack/table), [TanStack Router](https://github.com/tanstack/router), [TanStack Virtual](https://github.com/tanstack/virtual), [React Charts](https://github.com/TanStack/react-charts), [React Ranger](https://github.com/TanStack/ranger) + +## Visit [tanstack.com/query](https://tanstack.com/query) for docs, guides, API and more! + +## Quick Features + +- Transport/protocol/backend agnostic data fetching (REST, GraphQL, promises, whatever!) +- Auto Caching + Refetching (stale-while-revalidate, Window Refocus, Polling/Realtime) +- Parallel + Dependent Queries +- Mutations + Reactive Query Refetching +- Multi-layer Cache + Automatic Garbage Collection +- Paginated + Cursor-based Queries +- Load-More + Infinite Scroll Queries w/ Scroll Recovery +- Request Cancellation +- [React Suspense](https://reactjs.org/docs/concurrent-mode-suspense.html) + Fetch-As-You-Render Query Prefetching +- Dedicated Devtools +- + + (depending on features imported) + +### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/) + + From f57c8dc15ec7cc20c674892eacd7596a4df39085 Mon Sep 17 00:00:00 2001 From: Girish Sontakke <61848210+girishsontakke@users.noreply.github.com> Date: Tue, 24 Jan 2023 16:22:11 +0530 Subject: [PATCH 33/37] feat(client components): add `use client` directive at the top of files having client components (#4738) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dominik Dorfmeister Co-authored-by: Fredrik Höglund --- packages/react-query-devtools/src/Explorer.tsx | 1 + packages/react-query-devtools/src/devtools.tsx | 1 + packages/react-query-devtools/src/theme.tsx | 1 + .../src/PersistQueryClientProvider.tsx | 1 + packages/react-query/src/Hydrate.tsx | 1 + packages/react-query/src/QueryClientProvider.tsx | 1 + packages/react-query/src/QueryErrorResetBoundary.tsx | 1 + packages/react-query/src/isRestoring.tsx | 1 + 8 files changed, 8 insertions(+) diff --git a/packages/react-query-devtools/src/Explorer.tsx b/packages/react-query-devtools/src/Explorer.tsx index 04871143fd..5c40e54000 100644 --- a/packages/react-query-devtools/src/Explorer.tsx +++ b/packages/react-query-devtools/src/Explorer.tsx @@ -1,3 +1,4 @@ +'use client' import * as React from 'react' import { displayValue, styled } from './utils' diff --git a/packages/react-query-devtools/src/devtools.tsx b/packages/react-query-devtools/src/devtools.tsx index 9de970493c..1e23d69d0e 100644 --- a/packages/react-query-devtools/src/devtools.tsx +++ b/packages/react-query-devtools/src/devtools.tsx @@ -1,3 +1,4 @@ +'use client' import * as React from 'react' import { useSyncExternalStore } from './useSyncExternalStore' import type { diff --git a/packages/react-query-devtools/src/theme.tsx b/packages/react-query-devtools/src/theme.tsx index b8d1de0c2f..2530e5463f 100644 --- a/packages/react-query-devtools/src/theme.tsx +++ b/packages/react-query-devtools/src/theme.tsx @@ -1,3 +1,4 @@ +'use client' import * as React from 'react' export const defaultTheme = { diff --git a/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx b/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx index 5ccb2ff36e..ecfc916a2b 100644 --- a/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx +++ b/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx @@ -1,3 +1,4 @@ +'use client' import * as React from 'react' import type { PersistQueryClientOptions } from '@tanstack/query-persist-client-core' diff --git a/packages/react-query/src/Hydrate.tsx b/packages/react-query/src/Hydrate.tsx index a1b9fed01f..19d94a3681 100644 --- a/packages/react-query/src/Hydrate.tsx +++ b/packages/react-query/src/Hydrate.tsx @@ -1,3 +1,4 @@ +'use client' import * as React from 'react' import type { HydrateOptions } from '@tanstack/query-core' diff --git a/packages/react-query/src/QueryClientProvider.tsx b/packages/react-query/src/QueryClientProvider.tsx index 33a14f69cc..da4ba57880 100644 --- a/packages/react-query/src/QueryClientProvider.tsx +++ b/packages/react-query/src/QueryClientProvider.tsx @@ -1,3 +1,4 @@ +'use client' import * as React from 'react' import type { QueryClient } from '@tanstack/query-core' diff --git a/packages/react-query/src/QueryErrorResetBoundary.tsx b/packages/react-query/src/QueryErrorResetBoundary.tsx index 4a1fd73758..ba5fe3b2be 100644 --- a/packages/react-query/src/QueryErrorResetBoundary.tsx +++ b/packages/react-query/src/QueryErrorResetBoundary.tsx @@ -1,3 +1,4 @@ +'use client' import * as React from 'react' // CONTEXT diff --git a/packages/react-query/src/isRestoring.tsx b/packages/react-query/src/isRestoring.tsx index 3d8728e703..7d59c72507 100644 --- a/packages/react-query/src/isRestoring.tsx +++ b/packages/react-query/src/isRestoring.tsx @@ -1,3 +1,4 @@ +'use client' import * as React from 'react' const IsRestoringContext = React.createContext(false) From 53204fead507bf685a53436dadd107f1d3196268 Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Tue, 24 Jan 2023 10:58:19 +0000 Subject: [PATCH 34/37] release: v4.23.0 --- packages/react-query-devtools/package.json | 2 +- packages/react-query-persist-client/package.json | 2 +- packages/react-query/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-query-devtools/package.json b/packages/react-query-devtools/package.json index 82cc8a8d05..c5390fed13 100644 --- a/packages/react-query-devtools/package.json +++ b/packages/react-query-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-query-devtools", - "version": "4.22.4", + "version": "4.23.0", "description": "Developer tools to interact with and visualize the TanStack/react-query cache", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/react-query-persist-client/package.json b/packages/react-query-persist-client/package.json index 3d67b22bc6..b7cd81b938 100644 --- a/packages/react-query-persist-client/package.json +++ b/packages/react-query-persist-client/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-query-persist-client", - "version": "4.22.4", + "version": "4.23.0", "description": "React bindings to work with persisters in TanStack/react-query", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/react-query/package.json b/packages/react-query/package.json index 87353f7b05..acdda2b4e7 100644 --- a/packages/react-query/package.json +++ b/packages/react-query/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-query", - "version": "4.22.4", + "version": "4.23.0", "description": "Hooks for managing, caching and syncing asynchronous and remote data in React", "author": "tannerlinsley", "license": "MIT", From b9cb5f1464bcf3b2690e75e885093c3b239bfc9a Mon Sep 17 00:00:00 2001 From: Eric Filion Date: Tue, 24 Jan 2023 23:18:20 -0800 Subject: [PATCH 35/37] docs(ssr): add experimental app directory guide (#4568) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs(ssr): add experimental app directory guide * fixup: consistent code formatting * Revert "docs(ssr): add experimental app directory guide" This reverts commits: f6ef0164d6cbcc341ef15c999cf1e3eedf3a7336 5c48c7cffeadbdf953e45d7e4ec3080696a3d455 * [draft]: add experimental app directory guide * fixup: drop dehydrate options * fixup: layout.jsx consistent with create-next-app * fixup: note on using query-core vs react-query * docs(ssr): remove HydrateOnClient * docs(ssr): rewrite suspense and server-side fetching section * docs(ssr): tweaks * docs(ssr): prettier * docs: replace query-core imports with react-query imports Co-authored-by: Fredrik Höglund Co-authored-by: Dominik Dorfmeister --- docs/react/guides/ssr.md | 225 +++++++++++++++++++++++++++++++++++---- 1 file changed, 205 insertions(+), 20 deletions(-) diff --git a/docs/react/guides/ssr.md b/docs/react/guides/ssr.md index e825921abd..5ad911a9ec 100644 --- a/docs/react/guides/ssr.md +++ b/docs/react/guides/ssr.md @@ -18,7 +18,9 @@ The exact implementation of these mechanisms may vary from platform to platform, - Static Generation (SSG) - Server-side Rendering (SSR) -React Query supports both of these forms of pre-rendering regardless of what platform you may be using +React Query supports both of these forms of pre-rendering regardless of what platform you may be using. + +> Note: For notes about how to integrate with the new beta `/app`-folder in Next.js, see further down in this guide. ### Using `initialData` @@ -59,7 +61,11 @@ To support caching queries on the server and set up hydration: ```tsx // _app.jsx -import { Hydrate, QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { + Hydrate, + QueryClient, + QueryClientProvider, +} from '@tanstack/react-query' export default function MyApp({ Component, pageProps }) { const [queryClient] = React.useState(() => new QueryClient()) @@ -82,7 +88,7 @@ Now you are ready to prefetch some data in your pages with either [`getStaticPro ```tsx // pages/posts.jsx -import { dehydrate, QueryClient, useQuery } from '@tanstack/react-query'; +import { dehydrate, QueryClient, useQuery } from '@tanstack/react-query' export async function getStaticProps() { const queryClient = new QueryClient() @@ -103,7 +109,10 @@ function Posts() { // This query was not prefetched on the server and will not start // fetching until on the client, both patterns are fine to mix - const { data: otherData } = useQuery({ queryKey: ['posts-2'], queryFn: getPosts }) + const { data: otherData } = useQuery({ + queryKey: ['posts-2'], + queryFn: getPosts, + }) // ... } @@ -169,7 +178,11 @@ yarn add use-dehydrated-state ```tsx // root.tsx -import { Hydrate, QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { + Hydrate, + QueryClient, + QueryClientProvider, +} from '@tanstack/react-query' import { useDehydratedState } from 'use-dehydrated-state' @@ -196,7 +209,7 @@ Now you are ready to prefetch some data in your [`loader`](https://remix.run/doc ```tsx // pages/posts.tsx -import { dehydrate, QueryClient, useQuery } from '@tanstack/react-query'; +import { dehydrate, QueryClient, useQuery } from '@tanstack/react-query' export async function loader() { const queryClient = new QueryClient() @@ -213,7 +226,10 @@ function Posts() { // This query was not prefetched on the server and will not start // fetching until on the client, both patterns are fine to mix - const { data: otherData } = useQuery({ queryKey: ['posts-2'], queryFn: getPosts }) + const { data: otherData } = useQuery({ + queryKey: ['posts-2'], + queryFn: getPosts, + }) // ... } @@ -239,9 +255,14 @@ This guide is at-best, a high level overview of how SSR with React Query should > SECURITY NOTE: Serializing data with `JSON.stringify` can put you at risk for XSS-vulnerabilities, [this blog post explains why and how to solve it](https://medium.com/node-security/the-most-common-xss-vulnerability-in-react-js-applications-2bdffbcc1fa0) ```tsx -import { dehydrate, Hydrate, QueryClient, QueryClientProvider } from '@tanstack/react-query'; - -async function handleRequest (req, res) { +import { + dehydrate, + Hydrate, + QueryClient, + QueryClientProvider, +} from '@tanstack/react-query' + +async function handleRequest(req, res) { const queryClient = new QueryClient() await queryClient.prefetchQuery(['key'], fn) const dehydratedState = dehydrate(queryClient) @@ -251,7 +272,7 @@ async function handleRequest (req, res) { - + , ) res.send(` @@ -276,7 +297,11 @@ async function handleRequest (req, res) { - Render your app with the client provider and also **using the dehydrated state. This is extremely important! You must render both server and client using the same dehydrated state to ensure hydration on the client produces the exact same markup as the server.** ```tsx -import { Hydrate, QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { + Hydrate, + QueryClient, + QueryClientProvider, +} from '@tanstack/react-query' const dehydratedState = window.__REACT_QUERY_STATE__ @@ -288,10 +313,166 @@ ReactDOM.hydrate( , - document.getElementById('root') + document.getElementById('root'), ) ``` +## Using Experimental `app` Directory in Next.js 13 + +> **WARNING:** The `app` directory introduced in Next.js 13 is currently in beta, and it is not recommended for use in production. The API is not stable. +> +> This guide is provided as is to supply a quick start for early exploration of Next.js 13's experimental features and does not represent the final APIs. + +Both prefetching approaches, using `initialData` or ``, are available within the `app` directory. + +- Prefetch the data in a Server Component and prop drill `initialData` to Client Components + - Quick to set up for simple cases + - May need to prop drill through multiple layers of Client Components + - May need to prop drill to multiple Client Components using the same query + - Query refetching is based on when the page loads instead of when the data was prefetched on the server +- Prefetch the query on the server, dehydrate the cache and rehydrate it on the client with `` + - Requires slightly more setup up front + - No need to prop drill + - Query refetching is based on when the query was prefetched on the server + +### `` is required by both the `initialData` and `` prefetching approaches + +The hooks provided by the `react-query` package need to retrieve a `QueryClient` from their context. Wrap your component tree with `` and pass it an instance of `QueryClient`. + +```tsx +// app/providers.jsx +'use client' + +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' + +export default function Providers({ children }) { + const [queryClient] = React.useState(() => new QueryClient()) + + return ( + {children} + ) +} +``` + +```tsx +// app/layout.jsx +import Providers from './providers' + +export default function RootLayout({ children }) { + return ( + + + + {children} + + + ) +} +``` + +### Using `initialData` + +Fetch your initial data in a Server Component higher up in the component tree, and pass it to your Client Component as a prop. + +```tsx +// app/page.jsx +export default async function Home() { + const initialData = await getPosts() + + return +} +``` + +```tsx +// app/posts.jsx +'use client' + +import { useQuery } from '@tanstack/react-query' + +export function Posts(props) { + const { data } = useQuery({ + queryKey: ['posts'], + queryFn: getPosts, + initialData: props.posts, + }) + + // ... +} +``` + +### Using `` + +Create a request-scoped singleton instance of `QueryClient`. **This ensures that data is not shared between different users and requests, while still only creating the QueryClient once per request.** + +```tsx +// app/getQueryClient.jsx +import { QueryClient } from '@tanstack/react-query' +import { cache } from 'react' + +const getQueryClient = cache(() => new QueryClient()) +export default getQueryClient +``` + +Fetch your data in a Server Component higher up in the component tree than the Client Components that use the prefetched queries. Your prefetched queries will be available to all components deeper down the component tree. + +- Retrieve the `QueryClient` singleton instance +- Prefetch the data using the client's prefetchQuery method and wait for it to complete +- Use `dehydrate` to obtain the dehydrated state of the prefetched queries from the query cache +- Wrap the component tree that needs the prefetched queries inside ``, and provide it with the dehydrated state +- You can fetch inside multiple Server Components and use `` in multiple places + +> NOTE: TypeScript currently complains of a type error when using async Server Components. As a temporary workaround, use `{/* @ts-expect-error Server Component */}` when calling this component inside another. For more information, see [End-to-End Type Safety](https://beta.nextjs.org/docs/configuring/typescript#end-to-end-type-safety) in the Next.js 13 beta docs. + +```tsx +// app/hydratedPosts.jsx +import { dehydrate, Hydrate } from '@tanstack/react-query' +import getQueryClient from './getQueryClient' + +export default async function HydratedPosts() { + const queryClient = getQueryClient() + await queryClient.prefetchQuery(['posts'], getPosts) + const dehydratedState = dehydrate(queryClient) + + return ( + + + + ) +} +``` + +During server rendering, calls to `useQuery` nested within the `` Client Component will have access to prefetched data provided in the state property. + +```tsx +// app/posts.jsx +'use client' + +import { useQuery } from '@tanstack/react-query' + +export default function Posts() { + // This useQuery could just as well happen in some deeper child to + // the "HydratedPosts"-component, data will be available immediately either way + const { data } = useQuery({ queryKey: ['posts'], queryFn: getPosts }) + + // This query was not prefetched on the server and will not start + // fetching until on the client, both patterns are fine to mix + const { data: otherData } = useQuery({ + queryKey: ['posts-2'], + queryFn: getPosts, + }) + + // ... +} +``` + +As demonstrated, it's fine to prefetch some queries and let others fetch on the client. This means you can control what content server renders or not by adding or removing `prefetchQuery` for a specific query. + +### Streaming, Suspense and server-side fetching + +Right now, you always have to `await` the data in the Server Component. In the future, the goal is to be able to _start_ prefetching in a Server Component but not block rendering, instead streaming markup and data to the client incrementally as it gets available. This is currently lacking support in both React and Query. + +Similarily, you _must_ currently prefetch the data in a Server Component if you want it to be server rendered. A `useQuery()` call even with the `suspense` option enabled will not fetch data on the server, only on the client. We hope to support this in the future, but exact details are still unknown. + ## Custom SSR with suspense If you do not want to provide `prefetchQuery()` for all your queries in the SSR you can use suspense. @@ -299,29 +480,33 @@ If you do not want to provide `prefetchQuery()` for all your queries in the SSR ### Server ```tsx -import { dehydrate, QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { + dehydrate, + QueryClient, + QueryClientProvider, +} from '@tanstack/react-query' import ssrPrepass from 'react-ssr-prepass' -async function handleRequest (req, res) { +async function handleRequest(req, res) { const queryClient = new QueryClient() // React SSR does not support ErrorBoundary try { // Traverse the tree and fetch all Suspense data (thrown promises) - await ssrPrepass(); + await ssrPrepass() } catch (e) { - console.error(e); + console.error(e) // Send the index.html (without SSR) on error, so user can try to recover and see something - return res.sendFile('path/to/dist/index.html'); + return res.sendFile('path/to/dist/index.html') } const html = ReactDOM.renderToString( - + , ) - const dehydratedState = dehydrate(queryClient); + const dehydratedState = dehydrate(queryClient) res.send(` From 68c3e19bca66b07cc9f0224436d97243bb870410 Mon Sep 17 00:00:00 2001 From: Niko Mendo Date: Wed, 25 Jan 2023 04:18:49 -0300 Subject: [PATCH 36/37] docs: Fix variable reference issue on sveltekit doc (#4861) --- docs/svelte/ssr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/svelte/ssr.md b/docs/svelte/ssr.md index c9b6f210aa..8313e2ddf3 100644 --- a/docs/svelte/ssr.md +++ b/docs/svelte/ssr.md @@ -62,7 +62,7 @@ export const load: PageLoad = async () => { const query = createQuery({ queryKey: ['posts'], queryFn: getPosts, - initialData: posts + initialData: data.posts }) ``` From 9404df4c4cd3c8db2b4628a64d94c1ad1639609f Mon Sep 17 00:00:00 2001 From: Rendani Gangazhe Date: Wed, 25 Jan 2023 08:19:10 +0100 Subject: [PATCH 37/37] docs(svelte-query): Correctly type layout data when using prefetchQuery (#4852) --- docs/svelte/ssr.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/svelte/ssr.md b/docs/svelte/ssr.md index 8313e2ddf3..7efdcb2a7f 100644 --- a/docs/svelte/ssr.md +++ b/docs/svelte/ssr.md @@ -107,9 +107,9 @@ export const load: LayoutLoad = async () => { ```markdown