vike-solid-query 0.0.0 → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,185 @@
1
+ <!-- WARNING: keep links absolute in this file so they work on NPM too -->
2
+
3
+ [<img src="https://vike.dev/vike-readme.svg" align="right" height="90">](https://vike.dev)
4
+ [![npm version](https://img.shields.io/npm/v/vike-solid-query)](https://www.npmjs.com/package/vike-solid-query)
5
+
6
+ # `vike-solid-query`
7
+
8
+ Enables your Solid components to fetch data using [TanStack Query](https://tanstack.com/query/latest).
9
+
10
+ > [!NOTE]
11
+ > You'll also get [progressive rendering](https://vike.dev/streaming#progressive-rendering) and [supports](https://tanstack.com/query/latest/docs/framework/solid/reference/createQuery#usage-with-suspense) for triggering SolidJS Suspense and ErrorBoundary components when the query is in a pending or error state.
12
+
13
+ [Installation](#installation)
14
+ [Basic usage](#basic-usage)
15
+ [`QueryBoundary`](#queryboundary)
16
+ [`<head>` tags](#head-tags)
17
+ [See also](#see-also)
18
+
19
+ ## Installation
20
+
21
+ 1. `npm install @tanstack/solid-query vike-solid-query`
22
+ 2. Extend `+config.js`:
23
+ ```js
24
+ // pages/+config.js
25
+
26
+ import vikeSolid from 'vike-solid/config'
27
+ import vikeSolidQuery from 'vike-solid-query/config'
28
+
29
+ export default {
30
+ // ...
31
+ extends: [vikeSolid, vikeSolidQuery]
32
+ }
33
+ ```
34
+ > [!NOTE]
35
+ > The `vike-solid-query` extension requires [`vike-solid`](https://vike.dev/vike-solid).
36
+
37
+ ## Basic usage
38
+
39
+ ```jsx
40
+ import { createQuery } from "@tanstack/solid-query";
41
+ import { Suspense } from "solid-js";
42
+
43
+ const Movie = (props: { id }) => {
44
+ const query = createQuery(() => ({
45
+ queryKey: ["movies", props.id],
46
+ queryFn: () =>
47
+ fetch(`https://brillout.github.io/star-wars/api/films/${props.id}.json`)
48
+ .then((res) => res.json()),
49
+ }));
50
+
51
+ return (
52
+ <Suspense fallback={"Loading ..."}>
53
+ Title: <b>{query.data?.title}</b>
54
+ </Suspense>
55
+ )
56
+ }
57
+ ```
58
+
59
+ ## `QueryBoundary`
60
+
61
+ ```jsx
62
+ // Define loading fallback
63
+ <QueryBoundary query={query} loadingFallback={Loading}>
64
+ {(data) => <div>{data.something}</div>}
65
+ </QueryBoundary>
66
+ // Define loading and error fallback
67
+ <QueryBoundary query={query} loadingFallback={Loading} errorFallback={Error}>
68
+ {(data) => <div>{data.something}</div>}
69
+ </QueryBoundary>
70
+ // Define loading, error and not found fallback
71
+ <QueryBoundary query={query} loadingFallback={Loading} errorFallback={Error} notFoundFallback={NotFound}>
72
+ {(data) => <div>{data.something}</div>}
73
+ </QueryBoundary>
74
+ ```
75
+
76
+ > [!NOTE] Types
77
+ > `query: CreateQueryResult<T, Error>;`
78
+ > `loadingFallback?: JSX.Element;`
79
+ > `notFoundFallback?: JSX.Element;`
80
+ > `errorFallback?: JSX.Element | ((err: any, reset: () => void) => JSX.Element);`
81
+ > `children: (data: Exclude<T, null | false | undefined>) => JSX.Element;`
82
+
83
+ ```tsx
84
+ import { createQuery } from "@tanstack/solid-query";
85
+ import { QueryBoundary } from "vike-solid-query";
86
+
87
+ function Movie(props: { id: string }) {
88
+ const query = createQuery(() => ({
89
+ queryKey: ["movies", props.id],
90
+ queryFn: () =>
91
+ fetch(`https://brillout.github.io/star-wars/api/films/${props.id}.json`)
92
+ .then((res) => res.json())
93
+ }));
94
+
95
+ return (
96
+ <QueryBoundary
97
+ query={query}
98
+ loadingFallback={<p>Loading movie {props.id}</p>}
99
+ errorFallback={(err, reset) => (
100
+ <>
101
+ <div>Failed to load movie {props.id}</div>
102
+ <button
103
+ onClick={async () => {
104
+ reset();
105
+ await query.refetch();
106
+ }}
107
+ >
108
+ Retry
109
+ </button>
110
+ </>
111
+ )}
112
+ >
113
+ {(movie) => (
114
+ <div>
115
+ Title: <b>{movie.title}</b>
116
+ </div>
117
+ )}
118
+ </QueryBoundary>
119
+ );
120
+ }
121
+ ```
122
+
123
+ ## `<head>` tags
124
+
125
+ To set tags such as `<title>` and `<meta name="description">` based on fetched data, you can use [`<Config>`, `<Head>`, and `useConfig()`](https://vike.dev/useConfig).
126
+
127
+ ```js
128
+ import { createQuery } from "@tanstack/solid-query";
129
+ import { Config } from 'vike-solid/Config'
130
+ import { Head } from 'vike-solid/Head'
131
+ import { QueryBoundary } from "vike-solid-query";
132
+ import { For } from "solid-js";
133
+
134
+ function Movies() {
135
+ const query = createQuery(() => ({
136
+ queryKey: ["movies"],
137
+ queryFn: () => fetch('https://star-wars.brillout.com/api/films.json')
138
+ }));
139
+
140
+ return (
141
+ <QueryBoundary query={query} loadingFallback={<p>Loading movies ...</p>}>
142
+ {(movies) => (
143
+ <>
144
+ <Config title={`${movies.length} Star Wars movies`} />
145
+ <Head>
146
+ <meta name="description" content={`All ${movies.length} movies from the Star Wars franchise.`} />
147
+ </Head>
148
+ <h1>Star Wars Movies</h1>
149
+ <ol>
150
+ <For each={movies}>
151
+ {(movie) => (
152
+ <li>{movie.title}</li>
153
+ )}
154
+ </For>
155
+ </ol>
156
+ </>
157
+ )}
158
+ </QueryBoundary>
159
+ )
160
+ }
161
+ ```
162
+
163
+ ## Settings
164
+
165
+ You can modify the defaults defined by [`QueryClient`](https://tanstack.com/query/latest/docs/reference/QueryClient).
166
+
167
+ ```js
168
+ // +config.js
169
+
170
+ export default {
171
+ queryClientConfig: {
172
+ defaultOptions: {
173
+ queries: {
174
+ staleTime: 60 * 1000
175
+ }
176
+ }
177
+ }
178
+ }
179
+ ```
180
+
181
+ ## See also
182
+
183
+ - [Example](https://github.com/vikejs/vike-solid/tree/main/examples/solid-query)
184
+ - [TanStack Query > CreateQuery > Usage with Suspense](https://tanstack.com/query/latest/docs/framework/solid/reference/createQuery#usage-with-suspense)
185
+ - [Vike > Data Fetching](https://vike.dev/data-fetching)
@@ -0,0 +1,34 @@
1
+ import { QueryClientConfig } from '@tanstack/solid-query';
2
+
3
+ declare const _default: {
4
+ name: string;
5
+ require: {
6
+ "vike-solid": string;
7
+ };
8
+ Wrapper: "import:vike-solid-query/__internal/integration/Wrapper:default";
9
+ queryClientConfig: {
10
+ defaultOptions: {
11
+ queries: {
12
+ staleTime: number;
13
+ };
14
+ };
15
+ };
16
+ meta: {
17
+ queryClientConfig: {
18
+ env: {
19
+ server: true;
20
+ client: true;
21
+ };
22
+ };
23
+ };
24
+ };
25
+
26
+ declare global {
27
+ namespace Vike {
28
+ interface Config {
29
+ queryClientConfig?: QueryClientConfig;
30
+ }
31
+ }
32
+ }
33
+
34
+ export { _default as default };
@@ -0,0 +1,24 @@
1
+ var _config = {
2
+ name: "vike-solid-query",
3
+ require: {
4
+ "vike-solid": ">=0.7.3"
5
+ },
6
+ Wrapper: "import:vike-solid-query/__internal/integration/Wrapper:default",
7
+ queryClientConfig: {
8
+ defaultOptions: {
9
+ queries: {
10
+ staleTime: 5000
11
+ }
12
+ }
13
+ },
14
+ meta: {
15
+ queryClientConfig: {
16
+ env: {
17
+ server: true,
18
+ client: true
19
+ }
20
+ }
21
+ }
22
+ };
23
+
24
+ export { _config as default };
@@ -0,0 +1,7 @@
1
+ import { JSX } from 'solid-js';
2
+
3
+ declare function Wrapper(props: {
4
+ children: JSX.Element;
5
+ }): JSX.Element;
6
+
7
+ export { Wrapper as default };
@@ -0,0 +1,16 @@
1
+ import { createComponent } from 'solid-js/web';
2
+ import { QueryClient, QueryClientProvider } from '@tanstack/solid-query';
3
+ import { usePageContext } from 'vike-solid/usePageContext';
4
+
5
+ function Wrapper(props) {
6
+ const pageContext = usePageContext();
7
+ const queryClient = new QueryClient(pageContext.config.queryClientConfig);
8
+ return createComponent(QueryClientProvider, {
9
+ client: queryClient,
10
+ get children() {
11
+ return props.children;
12
+ }
13
+ });
14
+ }
15
+
16
+ export { Wrapper as default };
@@ -0,0 +1,26 @@
1
+ import type { CreateQueryResult } from "@tanstack/solid-query";
2
+ import type { JSX } from "solid-js";
3
+ export interface QueryBoundaryProps<T = unknown> {
4
+ query: CreateQueryResult<T, Error>;
5
+ /**
6
+ * Triggered when the data is initially loading.
7
+ */
8
+ loadingFallback?: JSX.Element;
9
+ /**
10
+ * Triggered when fetching is complete, but the returned data was falsey.
11
+ */
12
+ notFoundFallback?: JSX.Element;
13
+ /**
14
+ * Triggered when the query results in an error.
15
+ */
16
+ errorFallback?: JSX.Element | ((err: any, reset: () => void) => JSX.Element);
17
+ /**
18
+ * Triggered when fetching is complete, and the returned data is not falsey.
19
+ */
20
+ children: (data: Exclude<T, null | false | undefined>) => JSX.Element;
21
+ }
22
+ /**
23
+ * Convenience wrapper that handles suspense and errors for queries. Makes the results of query.data available to
24
+ * children (as a render prop) in a type-safe way.
25
+ */
26
+ export declare function QueryBoundary<T>(props: QueryBoundaryProps<T>): JSX.Element;
@@ -0,0 +1,37 @@
1
+ import { ErrorBoundary, Match, Suspense, Switch } from "solid-js";
2
+ /**
3
+ * Convenience wrapper that handles suspense and errors for queries. Makes the results of query.data available to
4
+ * children (as a render prop) in a type-safe way.
5
+ */
6
+ export function QueryBoundary(props) {
7
+ return (<ErrorBoundary fallback={props.errorFallback
8
+ ? props.errorFallback
9
+ : (err, reset) => (<div>
10
+ <div class="query-boundary-error">{err.toString()}</div>
11
+ <button onClick={async () => {
12
+ reset();
13
+ await props.query.refetch();
14
+ }}>
15
+ Retry
16
+ </button>
17
+ </div>)}>
18
+ <Suspense fallback={props.loadingFallback}>
19
+ <Switch>
20
+ <Match when={!props.query.isFetching && !props.query.data}>
21
+ {props.notFoundFallback ? (props.notFoundFallback) : (<>
22
+ <div>Not Found,</div>
23
+ <button onClick={async () => {
24
+ await props.query.refetch();
25
+ }}>
26
+ Refetch
27
+ </button>
28
+ </>)}
29
+ </Match>
30
+
31
+ <Match when={props.query.data}>
32
+ {props.children(props.query.data)}
33
+ </Match>
34
+ </Switch>
35
+ </Suspense>
36
+ </ErrorBoundary>);
37
+ }
@@ -0,0 +1 @@
1
+ export { QueryBoundary } from "./QueryBoundary";
@@ -0,0 +1 @@
1
+ export { QueryBoundary } from "./QueryBoundary";
package/package.json CHANGED
@@ -1,4 +1,53 @@
1
1
  {
2
2
  "name": "vike-solid-query",
3
- "version": "0.0.0"
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "rollup -c rollup.config.js --watch",
7
+ "dev:typecheck": "tsc --noEmit --watch",
8
+ "build": "rollup -c rollup.config.js && tsc",
9
+ "release": "LANG=en_US release-me patch",
10
+ "release:minor": "LANG=en_US release-me minor",
11
+ "release:commit": "LANG=en_US release-me commit"
12
+ },
13
+ "peerDependencies": {
14
+ "@tanstack/solid-query": ">=5.0.0",
15
+ "solid-js": "^1.8.7",
16
+ "vike-solid": ">=0.7.3"
17
+ },
18
+ "devDependencies": {
19
+ "@brillout/release-me": "^0.4.0",
20
+ "@rollup/plugin-babel": "6.0.4",
21
+ "@rollup/plugin-node-resolve": "15.2.3",
22
+ "@tanstack/solid-query": "^5.52.2",
23
+ "rimraf": "^6.0.1",
24
+ "rollup": "^4.21.2",
25
+ "rollup-plugin-dts": "6.1.1",
26
+ "solid-js": "^1.8.22",
27
+ "tsup": "^8.2.4",
28
+ "typescript": "^5.5.4",
29
+ "vike": "^0.4.193",
30
+ "vike-solid": "^0.7.3",
31
+ "vite": "5.4.2"
32
+ },
33
+ "exports": {
34
+ ".": "./dist/src/index.js",
35
+ "./config": "./dist/integration/+config.js",
36
+ "./__internal/integration/Wrapper": "./dist/integration/Wrapper.js"
37
+ },
38
+ "typesVersions": {
39
+ "*": {
40
+ "config": [
41
+ "dist/integration/+config.d.ts"
42
+ ],
43
+ "__internal/integration/Wrapper": [
44
+ "dist/integration/Wrapper.d.ts"
45
+ ]
46
+ }
47
+ },
48
+ "files": [
49
+ "dist/"
50
+ ],
51
+ "repository": "github:vikejs/vike-solid",
52
+ "license": "MIT"
4
53
  }
package/readme.md DELETED
@@ -1,3 +0,0 @@
1
- This is work in progress, stay tuned...
2
-
3
- If I didn't publish anything in a while and you want this package, then reach out and I'll give it away.