eden-tanstack-query 0.0.1 → 0.0.3

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 CHANGED
@@ -1,4 +1,4 @@
1
- # @elysiajs/eden-tanstack-query
1
+ # eden-tanstack-query
2
2
 
3
3
  A TanStack Query integration for [Eden Treaty](https://eden.ts), the type-safe client for [Elysia](https://elysiajs.com).
4
4
 
@@ -15,7 +15,7 @@ A TanStack Query integration for [Eden Treaty](https://eden.ts), the type-safe c
15
15
  ## Installation
16
16
 
17
17
  ```bash
18
- bun add @elysiajs/eden-tanstack-query @tanstack/query-core
18
+ bun add eden-tanstack-query @tanstack/query-core
19
19
  ```
20
20
 
21
21
  ## Basic Usage
@@ -24,7 +24,7 @@ bun add @elysiajs/eden-tanstack-query @tanstack/query-core
24
24
 
25
25
  ```typescript
26
26
  import { treaty } from '@elysiajs/eden/treaty2'
27
- import { createEdenQuery } from '@elysiajs/eden-tanstack-query'
27
+ import { createEdenQuery } from 'eden-tanstack-query'
28
28
  import { useQuery } from '@tanstack/svelte-query'
29
29
 
30
30
  // Your Elysia app type
@@ -91,19 +91,56 @@ const data = queryClient.getQueryData(eden.users.get.queryKey())
91
91
 
92
92
  ## Error Handling
93
93
 
94
- ### Throw on Error (Default for most apps)
94
+ ### Global Error Handler
95
+
96
+ Define error handling logic once when creating the client:
97
+
98
+ ```typescript
99
+ import type { EdenErrorContext } from 'eden-tanstack-query'
100
+
101
+ const eden = createEdenQuery<App>('http://localhost:8080', {
102
+ throwOnError: true,
103
+ onError: ({ error, path, method, type }: EdenErrorContext) => {
104
+ // Runs for ALL queries and mutations before throwing
105
+
106
+ if (error.status === 401) {
107
+ authStore.logout()
108
+ router.push('/login')
109
+ }
110
+
111
+ if (error.status === 403) {
112
+ toast.error('Not authorized')
113
+ }
114
+
115
+ if (error.status >= 500) {
116
+ toast.error('Server error, please try again')
117
+ logger.error('API Error', { path, method, error })
118
+ }
119
+ }
120
+ })
121
+ ```
122
+
123
+ The `EdenErrorContext` provides:
124
+ - `error` - The `EdenFetchError` with status and value
125
+ - `queryKey` - The generated query key
126
+ - `method` - HTTP method ('get', 'post', etc.)
127
+ - `path` - API path segments (['users', 'posts'])
128
+ - `input` - The request input
129
+ - `type` - Either 'query' or 'mutation'
130
+
131
+ ### Throw on Error (Default)
95
132
 
96
133
  ```typescript
97
134
  const eden = createEdenQuery<App>('http://localhost:8080', {
98
135
  throwOnError: true
99
136
  })
100
137
 
138
+ // Per-query error handling (in addition to global handler)
101
139
  useQuery(eden.users.get.queryOptions(undefined, {
102
140
  onError: (error: EdenFetchError) => {
103
- // error.status and error.value are available
104
- // extra context is attached: error.queryKey, error.method, error.path, error.input
105
- if (error.status === 401) {
106
- router.push('/login')
141
+ // Runs after global handler, only for this query
142
+ if (error.status === 404) {
143
+ // Handle not found specifically for this query
107
144
  }
108
145
  }
109
146
  }))
@@ -123,6 +160,23 @@ const eden = createEdenQuery<App>('http://localhost:8080', {
123
160
  })
124
161
  ```
125
162
 
163
+ ### Known Limitation: `onSuccess` Data Type
164
+
165
+ When using `throwOnError: true`, errors are thrown before reaching `onSuccess`. However, TypeScript cannot narrow the data type at compile-time since `throwOnError` is a runtime configuration. This means the `data` parameter in `onSuccess` may still include error union types from your response schema.
166
+
167
+ **Workaround**: Use the `vars` parameter instead of `data` when you only need input values (e.g., for cache invalidation):
168
+
169
+ ```typescript
170
+ useMutation(eden.users.post.mutationOptions({
171
+ onSuccess: (_, vars) => {
172
+ // Use vars instead of data for invalidation
173
+ queryClient.invalidateQueries({
174
+ queryKey: eden.users({ id: vars.userId }).get.queryKey()
175
+ })
176
+ }
177
+ }))
178
+ ```
179
+
126
180
  ## Advanced Usage
127
181
 
128
182
  ### Custom Eden Treaty Options
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { QueryFilters, QueryKey, QueryObserverOptions, QueryFunctionContext, MutationOptions, InfiniteQueryObserverOptions } from '@tanstack/query-core';
1
+ import * as _elysiajs_eden from '@elysiajs/eden';
2
2
  import { EdenFetchError } from '@elysiajs/eden';
3
+ import { QueryFilters, QueryKey, QueryObserverOptions, QueryFunctionContext, MutationOptions, InfiniteQueryObserverOptions } from '@tanstack/query-core';
3
4
  import { Elysia } from 'elysia';
4
5
  import { Treaty } from '@elysiajs/eden/treaty2';
5
6
  export { Treaty, treaty } from '@elysiajs/eden/treaty2';
@@ -13,9 +14,18 @@ interface EdenThrowOnErrorContext {
13
14
  input: unknown;
14
15
  }
15
16
  type EdenThrowOnError = ((queryKey: readonly unknown[], status: number) => boolean) | ((context: EdenThrowOnErrorContext) => boolean);
17
+ interface EdenErrorContext {
18
+ error: _elysiajs_eden.EdenFetchError;
19
+ queryKey: readonly unknown[];
20
+ method: HTTPMethod;
21
+ path: string[];
22
+ input: unknown;
23
+ type: 'query' | 'mutation';
24
+ }
16
25
  interface EdenQueryConfig {
17
26
  throwOnError?: boolean | EdenThrowOnError;
18
27
  queryKeyPrefix?: string | string[];
28
+ onError?: (context: EdenErrorContext) => void;
19
29
  }
20
30
  interface EdenOptions<TEden = unknown> {
21
31
  eden?: TEden;
@@ -56,4 +66,4 @@ declare function createEdenQuery<App extends Elysia<any, any, any, any, any, any
56
66
  treaty?: Treaty.Config;
57
67
  }): EdenQueryify<Treaty.Create<App>>;
58
68
 
59
- export { type EdenInfiniteQueryOptions, type EdenMutationMethod, type EdenMutationOptions, type EdenOptions, type EdenQueryConfig, type EdenQueryKey, type EdenQueryMethod, type EdenQueryOptions, type EdenQueryify, type EdenThrowOnError, type EdenThrowOnErrorContext, type HTTPMethod, createEdenQuery };
69
+ export { type EdenErrorContext, type EdenInfiniteQueryOptions, type EdenMutationMethod, type EdenMutationOptions, type EdenOptions, type EdenQueryConfig, type EdenQueryKey, type EdenQueryMethod, type EdenQueryOptions, type EdenQueryify, type EdenThrowOnError, type EdenThrowOnErrorContext, type HTTPMethod, createEdenQuery };
package/dist/index.js CHANGED
@@ -50,6 +50,14 @@ function createQueryOptions(treatyCall, paths, method, globalConfig) {
50
50
  error.input = finalInput;
51
51
  error.response = result.response;
52
52
  error.headers = result.headers;
53
+ globalConfig.onError?.({
54
+ error,
55
+ queryKey,
56
+ method,
57
+ path: paths,
58
+ input: finalInput,
59
+ type: "query"
60
+ });
53
61
  if (shouldThrowOnError(globalConfig, {
54
62
  queryKey,
55
63
  status: result.status,
@@ -110,6 +118,14 @@ function createMutationOptions(treatyCall, paths, method, globalConfig) {
110
118
  error.input = variables;
111
119
  error.response = result.response;
112
120
  error.headers = result.headers;
121
+ globalConfig.onError?.({
122
+ error,
123
+ queryKey: mutationKey,
124
+ method,
125
+ path: paths,
126
+ input: variables,
127
+ type: "mutation"
128
+ });
113
129
  if (shouldThrowOnError2(globalConfig, {
114
130
  queryKey: mutationKey,
115
131
  status: result.status,
@@ -186,7 +202,8 @@ function createEdenQuery(domain, options) {
186
202
  [],
187
203
  {
188
204
  throwOnError: options?.throwOnError ?? true,
189
- queryKeyPrefix: options?.queryKeyPrefix
205
+ queryKeyPrefix: options?.queryKeyPrefix,
206
+ onError: options?.onError
190
207
  }
191
208
  );
192
209
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eden-tanstack-query",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "TanStack Query integration for Eden Treaty",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,14 +21,14 @@
21
21
  },
22
22
  "peerDependencies": {
23
23
  "@elysiajs/eden": ">=1.0.0",
24
- "@tanstack/query-core": "^5.0.0"
24
+ "@tanstack/query-core": "^5.90.12"
25
25
  },
26
26
  "devDependencies": {
27
- "@elysiajs/eden": "file:../..",
28
- "@tanstack/react-query": "^5.0.0",
29
- "@tanstack/svelte-query": "^5.0.0",
27
+ "@elysiajs/eden": "^1.4.6",
28
+ "@tanstack/react-query": "^5.90.12",
29
+ "@tanstack/svelte-query": "^5.90.2",
30
30
  "bun-types": "latest",
31
- "typescript": "^5.0.0"
31
+ "typescript": "^5.9.3"
32
32
  },
33
33
  "keywords": [
34
34
  "elysia",