katanakit-js 4.0.2 → 4.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.
Files changed (54) hide show
  1. package/README.md +54 -55
  2. package/dist/adapters/angular/index.d.ts +1 -0
  3. package/dist/adapters/angular/index.d.ts.map +1 -1
  4. package/dist/adapters/angular/index.js +1 -0
  5. package/dist/adapters/angular/index.js.map +1 -1
  6. package/dist/adapters/angular/query.d.ts +56 -73
  7. package/dist/adapters/angular/query.d.ts.map +1 -1
  8. package/dist/adapters/angular/query.js +66 -129
  9. package/dist/adapters/angular/query.js.map +1 -1
  10. package/dist/adapters/react/index.d.ts +1 -0
  11. package/dist/adapters/react/index.d.ts.map +1 -1
  12. package/dist/adapters/react/index.js +1 -0
  13. package/dist/adapters/react/index.js.map +1 -1
  14. package/dist/adapters/react/query.d.ts +27 -72
  15. package/dist/adapters/react/query.d.ts.map +1 -1
  16. package/dist/adapters/react/query.js +51 -165
  17. package/dist/adapters/react/query.js.map +1 -1
  18. package/dist/adapters/solid/index.d.ts +1 -0
  19. package/dist/adapters/solid/index.d.ts.map +1 -1
  20. package/dist/adapters/solid/index.js +1 -0
  21. package/dist/adapters/solid/index.js.map +1 -1
  22. package/dist/adapters/solid/query.d.ts +32 -74
  23. package/dist/adapters/solid/query.d.ts.map +1 -1
  24. package/dist/adapters/solid/query.js +56 -131
  25. package/dist/adapters/solid/query.js.map +1 -1
  26. package/dist/adapters/svelte/index.d.ts +1 -0
  27. package/dist/adapters/svelte/index.d.ts.map +1 -1
  28. package/dist/adapters/svelte/index.js +1 -0
  29. package/dist/adapters/svelte/index.js.map +1 -1
  30. package/dist/adapters/svelte/query.d.ts +24 -72
  31. package/dist/adapters/svelte/query.d.ts.map +1 -1
  32. package/dist/adapters/svelte/query.js +41 -135
  33. package/dist/adapters/svelte/query.js.map +1 -1
  34. package/dist/adapters/vanilla/index.d.ts +3 -0
  35. package/dist/adapters/vanilla/index.d.ts.map +1 -0
  36. package/dist/adapters/vanilla/index.js +3 -0
  37. package/dist/adapters/vanilla/index.js.map +1 -0
  38. package/dist/adapters/vanilla/query.d.ts +69 -0
  39. package/dist/adapters/vanilla/query.d.ts.map +1 -0
  40. package/dist/adapters/vanilla/query.js +76 -0
  41. package/dist/adapters/vanilla/query.js.map +1 -0
  42. package/dist/adapters/vue/index.d.ts +1 -0
  43. package/dist/adapters/vue/index.d.ts.map +1 -1
  44. package/dist/adapters/vue/index.js +1 -0
  45. package/dist/adapters/vue/index.js.map +1 -1
  46. package/dist/adapters/vue/query.d.ts +35 -86
  47. package/dist/adapters/vue/query.d.ts.map +1 -1
  48. package/dist/adapters/vue/query.js +57 -168
  49. package/dist/adapters/vue/query.js.map +1 -1
  50. package/dist/core/services/query.service.d.ts +87 -134
  51. package/dist/core/services/query.service.d.ts.map +1 -1
  52. package/dist/core/services/query.service.js +99 -378
  53. package/dist/core/services/query.service.js.map +1 -1
  54. package/package.json +10 -3
package/README.md CHANGED
@@ -250,49 +250,48 @@ await usePost("myApi", "upload", form);
250
250
 
251
251
  ### Full example
252
252
 
253
- See [`examples/api-manager/demo.ts`](https://github.com/senseikatana/katanakit/tree/main/examples/api-manager) for a runnable demo
253
+ See [`examples/api-manager/demo.ts`](https://github.com/senseikatana/katanakit-js/tree/main/examples/api-manager) for a runnable demo
254
254
  covering all CRUD operations, auth injection, URL building, and error handling
255
255
  against a real API (JSONPlaceholder).
256
256
 
257
257
  ## QueryClient — Cached Data Fetching
258
258
 
259
- The QueryClient is a data-fetching and caching layer built on the reactive kernel.
260
- It integrates with the API manager — your `queryFn` typically calls `useGetApi` or
261
- `useFetch` and returns the Safe Result.
259
+ The query layer is powered by **TanStack Query Core**, bundled as a dependency —
260
+ install `katanakit-js` and the engine comes with it. KatanaKit re-exports the full
261
+ `@tanstack/query-core` API and adds framework bindings plus a bridge for the
262
+ Safe Result pattern.
262
263
 
263
264
  ```ts
264
- import { QueryClient, useQueryClient } from "katanakit-js";
265
+ import { useQueryClient, useInitQueryClient, useSafeQueryFn } from "katanakit-js";
265
266
  import { useGetApi } from "katanakit-js";
266
267
 
267
- // Initialize once (global singleton).
268
- const qc = useQueryClient();
269
-
270
- // Fetch with cache, stale-while-revalidate, retry, and dedup.
271
- const pokemon = await qc.fetchQuery<Pokemon>({
272
- queryKey: ["pokemon", 25],
273
- queryFn: () => useGetApi<Pokemon>("pokeapi", "pokemonById", { params: { id: 25 } }),
274
- staleTime: 60_000, // Cache is fresh for 60s.
275
- retry: 3, // Retry 3 times on failure.
276
- refetchOnWindowFocus: true,
268
+ // Configure the shared client once (defaults for every query).
269
+ useInitQueryClient({
270
+ defaultOptions: { queries: { staleTime: 60_000, retry: 2 } },
277
271
  });
272
+
273
+ // Access it anywhere to invalidate, prefetch, or set data.
274
+ const qc = useQueryClient();
275
+ await qc.invalidateQueries({ queryKey: ["pokemon"] });
278
276
  ```
279
277
 
280
278
  ### Vue composables
281
279
 
282
280
  ```vue
283
281
  <script setup>
284
- import { useQuery, useMutation, useQueryClient } from "katanakit-js/adapters/vue";
282
+ import { useQuery, useMutation, useQueryClient, useSafeQueryFn } from "katanakit-js/adapters/vue";
285
283
  import { useGetApi, usePost } from "katanakit-js";
286
284
 
287
285
  const qc = useQueryClient();
288
286
 
289
- const { data, isLoading, error, refetch } = useQuery({
290
- queryKey: () => ["users"],
291
- queryFn: () => useGetApi<User[]>("myApi", "users"),
287
+ const query = useQuery({
288
+ queryKey: ["users"],
289
+ queryFn: useSafeQueryFn(() => useGetApi<User[]>("myApi", "users")),
292
290
  staleTime: 30_000,
293
291
  });
292
+ // query.data, query.isPending, query.isFetching, query.error, query.status…
294
293
 
295
- const { mutate, isLoading: mutating } = useMutation({
294
+ const mutation = useMutation({
296
295
  mutationFn: (name: string) => usePost("myApi", "createUser", { name }),
297
296
  onSuccess: () => qc.invalidateQueries({ queryKey: ["users"] }),
298
297
  });
@@ -436,7 +435,7 @@ Also on the main barrel:
436
435
  | `useResetSession` | `(sessionId) => Promise<void>` |
437
436
  | `useCreateMemoryStore` | `() => ConversationStore` |
438
437
 
439
- Then start a channel (see below). Copy keys from [`.env.example`](https://github.com/senseikatana/katanakit/blob/main/.env.example):
438
+ Then start a channel (see below). Copy keys from [`.env.example`](https://github.com/senseikatana/katanakit-js/blob/main/.env.example):
440
439
 
441
440
  ```env
442
441
  DASHSCOPE_API_KEY=
@@ -575,7 +574,7 @@ owns the database, run `prisma contract emit` then `prisma db init` in that app.
575
574
 
576
575
  ### Real use case
577
576
 
578
- [`examples/assistant/`](https://github.com/senseikatana/katanakit/tree/main/examples/assistant) is a generic digital assistant with two demo tools:
577
+ [`examples/assistant/`](https://github.com/senseikatana/katanakit-js/tree/main/examples/assistant) is a generic digital assistant with two demo tools:
579
578
  `readFile` on `knowledge-base.md` and `saveNote` to `notes.jsonl`.
580
579
 
581
580
  ```bash
@@ -630,7 +629,7 @@ import { useUnwrap } from "katanakit-js/adapters/nuxt"; // Nuxt only
630
629
  </script>
631
630
  ```
632
631
 
633
- See [Getting Started](https://senseikatana.com/katanakit-js/docs/guides/getting-started/) for full recipes.
632
+ See [Getting Started](https://docs.senseikatana.com/docs/guides/getting-started/) for full recipes.
634
633
 
635
634
  ## Framework Adapters
636
635
 
@@ -850,17 +849,17 @@ if (users.ok) users.data.results.forEach((u) => console.log(u.name));
850
849
 
851
850
  #### Framework examples
852
851
 
853
- | Framework | Example | Description |
854
- | ----------- | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------- |
855
- | **Vue 3** | [`examples/notion/vue-blog.vue`](https://github.com/senseikatana/katanakit/tree/main/examples/notion/vue-blog.vue) | Blog listing with `useQuery` composable |
856
- | **Vue 3** | [`examples/notion/vue-post.vue`](https://github.com/senseikatana/katanakit/tree/main/examples/notion/vue-post.vue) | Single post view |
857
- | **Nuxt 3** | [`examples/notion/nuxt-blog.vue`](https://github.com/senseikatana/katanakit/tree/main/examples/notion/nuxt-blog.vue) | SSR blog listing with `useAsyncData` |
858
- | **Nuxt 3** | [`examples/notion/nuxt-post.vue`](https://github.com/senseikatana/katanakit/tree/main/examples/notion/nuxt-post.vue) | SSR single post view |
859
- | **Astro** | [`examples/notion/astro-blog.astro`](https://github.com/senseikatana/katanakit/tree/main/examples/notion/astro-blog.astro) | Static blog listing |
860
- | **Astro** | [`examples/notion/astro-[slug].astro`](https://github.com/senseikatana/katanakit/tree/main/examples/notion/astro-[slug].astro) | Dynamic `[slug]` route |
861
- | **Next.js** | [`examples/notion/next-blog.tsx`](https://github.com/senseikatana/katanakit/tree/main/examples/notion/next-blog.tsx) | Server component blog listing |
862
- | **Next.js** | [`examples/notion/next-[slug].tsx`](https://github.com/senseikatana/katanakit/tree/main/examples/notion/next-[slug].tsx) | Dynamic `[slug]` page |
863
- | **Node.js** | [`examples/notion/demo.ts`](https://github.com/senseikatana/katanakit/tree/main/examples/notion/demo.ts) | Runnable demo covering all Notion operations |
852
+ | Framework | Example | Description |
853
+ | ----------- | --------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
854
+ | **Vue 3** | [`examples/notion/vue-blog.vue`](https://github.com/senseikatana/katanakit-js/tree/main/examples/notion/vue-blog.vue) | Blog listing with `useQuery` composable |
855
+ | **Vue 3** | [`examples/notion/vue-post.vue`](https://github.com/senseikatana/katanakit-js/tree/main/examples/notion/vue-post.vue) | Single post view |
856
+ | **Nuxt 3** | [`examples/notion/nuxt-blog.vue`](https://github.com/senseikatana/katanakit-js/tree/main/examples/notion/nuxt-blog.vue) | SSR blog listing with `useAsyncData` |
857
+ | **Nuxt 3** | [`examples/notion/nuxt-post.vue`](https://github.com/senseikatana/katanakit-js/tree/main/examples/notion/nuxt-post.vue) | SSR single post view |
858
+ | **Astro** | [`examples/notion/astro-blog.astro`](https://github.com/senseikatana/katanakit-js/tree/main/examples/notion/astro-blog.astro) | Static blog listing |
859
+ | **Astro** | [`examples/notion/astro-[slug].astro`](https://github.com/senseikatana/katanakit-js/tree/main/examples/notion/astro-[slug].astro) | Dynamic `[slug]` route |
860
+ | **Next.js** | [`examples/notion/next-blog.tsx`](https://github.com/senseikatana/katanakit-js/tree/main/examples/notion/next-blog.tsx) | Server component blog listing |
861
+ | **Next.js** | [`examples/notion/next-[slug].tsx`](https://github.com/senseikatana/katanakit-js/tree/main/examples/notion/next-[slug].tsx) | Dynamic `[slug]` page |
862
+ | **Node.js** | [`examples/notion/demo.ts`](https://github.com/senseikatana/katanakit-js/tree/main/examples/notion/demo.ts) | Runnable demo covering all Notion operations |
864
863
 
865
864
  ### WordPress
866
865
 
@@ -1206,17 +1205,17 @@ const full = await useWpGetPosts({
1206
1205
 
1207
1206
  #### Framework examples
1208
1207
 
1209
- | Framework | Example | Description |
1210
- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ |
1211
- | **Vue 3** | [`examples/wordpress/vue-blog.vue`](https://github.com/senseikatana/katanakit/tree/main/examples/wordpress/vue-blog.vue) | Blog listing with categories, featured images, `_embed` |
1212
- | **Vue 3** | [`examples/wordpress/vue-post.vue`](https://github.com/senseikatana/katanakit/tree/main/examples/wordpress/vue-post.vue) | Single post view with embedded author |
1213
- | **Nuxt 3** | [`examples/wordpress/nuxt-blog.vue`](https://github.com/senseikatana/katanakit/tree/main/examples/wordpress/nuxt-blog.vue) | SSR blog listing with `useAsyncData` |
1214
- | **Nuxt 3** | [`examples/wordpress/nuxt-post.vue`](https://github.com/senseikatana/katanakit/tree/main/examples/wordpress/nuxt-post.vue) | SSR single post view |
1215
- | **Astro** | [`examples/wordpress/astro-blog.astro`](https://github.com/senseikatana/katanakit/tree/main/examples/wordpress/astro-blog.astro) | Static blog listing |
1216
- | **Astro** | [`examples/wordpress/astro-[slug].astro`](https://github.com/senseikatana/katanakit/tree/main/examples/wordpress/astro-[slug].astro) | Dynamic `[slug]` route |
1217
- | **Next.js** | [`examples/wordpress/next-blog.tsx`](https://github.com/senseikatana/katanakit/tree/main/examples/wordpress/next-blog.tsx) | Server component blog listing |
1218
- | **Next.js** | [`examples/wordpress/next-[slug].tsx`](https://github.com/senseikatana/katanakit/tree/main/examples/wordpress/next-[slug].tsx) | Dynamic `[slug]` page |
1219
- | **Node.js** | [`examples/wordpress/demo.ts`](https://github.com/senseikatana/katanakit/tree/main/examples/wordpress/demo.ts) | Runnable demo covering all WP operations, `_fields`, `_embed`, ACF |
1208
+ | Framework | Example | Description |
1209
+ | ----------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
1210
+ | **Vue 3** | [`examples/wordpress/vue-blog.vue`](https://github.com/senseikatana/katanakit-js/tree/main/examples/wordpress/vue-blog.vue) | Blog listing with categories, featured images, `_embed` |
1211
+ | **Vue 3** | [`examples/wordpress/vue-post.vue`](https://github.com/senseikatana/katanakit-js/tree/main/examples/wordpress/vue-post.vue) | Single post view with embedded author |
1212
+ | **Nuxt 3** | [`examples/wordpress/nuxt-blog.vue`](https://github.com/senseikatana/katanakit-js/tree/main/examples/wordpress/nuxt-blog.vue) | SSR blog listing with `useAsyncData` |
1213
+ | **Nuxt 3** | [`examples/wordpress/nuxt-post.vue`](https://github.com/senseikatana/katanakit-js/tree/main/examples/wordpress/nuxt-post.vue) | SSR single post view |
1214
+ | **Astro** | [`examples/wordpress/astro-blog.astro`](https://github.com/senseikatana/katanakit-js/tree/main/examples/wordpress/astro-blog.astro) | Static blog listing |
1215
+ | **Astro** | [`examples/wordpress/astro-[slug].astro`](https://github.com/senseikatana/katanakit-js/tree/main/examples/wordpress/astro-[slug].astro) | Dynamic `[slug]` route |
1216
+ | **Next.js** | [`examples/wordpress/next-blog.tsx`](https://github.com/senseikatana/katanakit-js/tree/main/examples/wordpress/next-blog.tsx) | Server component blog listing |
1217
+ | **Next.js** | [`examples/wordpress/next-[slug].tsx`](https://github.com/senseikatana/katanakit-js/tree/main/examples/wordpress/next-[slug].tsx) | Dynamic `[slug]` page |
1218
+ | **Node.js** | [`examples/wordpress/demo.ts`](https://github.com/senseikatana/katanakit-js/tree/main/examples/wordpress/demo.ts) | Runnable demo covering all WP operations, `_fields`, `_embed`, ACF |
1220
1219
 
1221
1220
  ## Contributing
1222
1221
 
@@ -1227,7 +1226,7 @@ better for everyone.
1227
1226
  ### Quick start
1228
1227
 
1229
1228
  ```bash
1230
- git clone https://github.com/senseikatana/katanakit.git
1229
+ git clone https://github.com/senseikatana/katanakit-js.git
1231
1230
  cd katanakit-js
1232
1231
  git checkout dev
1233
1232
  bun install
@@ -1236,8 +1235,8 @@ bun run check # verify everything works
1236
1235
 
1237
1236
  ### Ways to contribute
1238
1237
 
1239
- - **Report bugs** — [Open an issue](https://github.com/senseikatana/katanakit/issues) with a clear description and reproduction steps
1240
- - **Suggest features** — [Start a discussion](https://github.com/senseikatana/katanakit/discussions) to propose new ideas
1238
+ - **Report bugs** — [Open an issue](https://github.com/senseikatana/katanakit-js/issues) with a clear description and reproduction steps
1239
+ - **Suggest features** — [Start a discussion](https://github.com/senseikatana/katanakit-js/discussions) to propose new ideas
1241
1240
  - **Submit a PR** — Fork the repo, create a branch from `dev`, make your changes, and open a PR
1242
1241
  - **Improve docs** — Fix typos, add examples, or clarify explanations
1243
1242
  - **Add adapters** — Build integrations for new APIs or frameworks
@@ -1254,14 +1253,14 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for the full development contract.
1254
1253
 
1255
1254
  ## Documentation
1256
1255
 
1257
- The docs site is deployed with Render at [senseikatana.com/katanakit-js](https://senseikatana.com/katanakit-js/).
1256
+ The docs site is deployed with Cloudflare Pages at [docs.senseikatana.com](https://docs.senseikatana.com/).
1258
1257
 
1259
- - [Getting Started](https://senseikatana.com/katanakit-js/docs/guides/getting-started/)
1260
- - [Architecture](https://senseikatana.com/katanakit-js/docs/guides/architecture/)
1261
- - [UI Kit (Katana UI)](https://senseikatana.com/katanakit-js/docs/ui-kit/)
1262
- - [API Reference](https://senseikatana.com/katanakit-js/docs/api/)
1263
- - [Roadmap](https://senseikatana.com/katanakit-js/docs/guides/roadmap/)
1264
- - [Changelog](https://senseikatana.com/katanakit-js/docs/changelog/)
1258
+ - [Getting Started](https://docs.senseikatana.com/docs/guides/getting-started/)
1259
+ - [Architecture](https://docs.senseikatana.com/docs/guides/architecture/)
1260
+ - [UI Kit (Katana UI)](https://docs.senseikatana.com/docs/ui-kit/)
1261
+ - [API Reference](https://docs.senseikatana.com/docs/api/)
1262
+ - [Roadmap](https://docs.senseikatana.com/docs/guides/roadmap/)
1263
+ - [Changelog](https://docs.senseikatana.com/docs/changelog/)
1265
1264
 
1266
1265
  ## License
1267
1266
 
@@ -1,3 +1,4 @@
1
+ export { useCreateQueryClient, useInitQueryClient, useQueryClient, useSafeQueryFn, } from "../../core/services/query.service.js";
1
2
  export * from "./fetch.js";
2
3
  export * from "./query.js";
3
4
  export * from "./watch.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/angular/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/angular/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,cAAc,GACd,MAAM,sCAAsC,CAAC;AAC9C,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
@@ -1,3 +1,4 @@
1
+ export { useCreateQueryClient, useInitQueryClient, useQueryClient, useSafeQueryFn, } from "../../core/services/query.service.js";
1
2
  export * from "./fetch.js";
2
3
  export * from "./query.js";
3
4
  export * from "./watch.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/angular/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/angular/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,cAAc,GACd,MAAM,sCAAsC,CAAC;AAC9C,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
@@ -1,89 +1,71 @@
1
1
  import { type Signal } from "@angular/core";
2
- import { type QueryClient, type QueryKey, type QueryState } from "../../core/services/query.service.js";
3
- import type { ApiError, FetchResult } from "../../types/index.js";
4
- /** Configuration for `useQuery` (Angular signal factory). */
5
- export interface UseQueryConfig<T = unknown> {
6
- /** Cache key (stable array). */
7
- queryKey: QueryKey;
8
- /** Fetcher function returning a Safe Result. */
9
- queryFn: () => Promise<FetchResult<T>>;
10
- /** Time in ms before cached data is stale (default: 0). */
11
- staleTime?: number;
12
- /** Time in ms to keep unused data (default: 5 min). */
13
- cacheTime?: number;
14
- /** Retry count on failure (default: 3). */
15
- retry?: number;
16
- /** Base delay for exponential backoff (default: 1000). */
17
- retryDelay?: number;
18
- /** Whether the query is enabled (default: true). */
19
- enabled?: boolean;
2
+ import { type FetchStatus, type MutationObserverOptions, type MutationStatus, type QueryClient, type QueryObserverOptions, type QueryObserverResult, type QueryStatus, type RefetchOptions } from "@tanstack/query-core";
3
+ /** Signal-based query result returned by {@link useQuery}. */
4
+ export interface AngularQueryResult<TData = unknown, TError = Error> {
5
+ readonly data: Signal<TData | undefined>;
6
+ readonly error: Signal<TError | null>;
7
+ readonly isPending: Signal<boolean>;
8
+ readonly isFetching: Signal<boolean>;
9
+ readonly isLoading: Signal<boolean>;
10
+ readonly isSuccess: Signal<boolean>;
11
+ readonly isError: Signal<boolean>;
12
+ readonly isStale: Signal<boolean>;
13
+ readonly status: Signal<QueryStatus>;
14
+ readonly fetchStatus: Signal<FetchStatus>;
15
+ readonly refetch: (options?: RefetchOptions) => Promise<QueryObserverResult<TData, TError>>;
20
16
  }
21
- /** Reactive return value of `useQuery` (Angular signals). */
22
- export interface UseQueryReturn<T = unknown> {
23
- data: Signal<T | null>;
24
- error: Signal<ApiError | null>;
25
- isLoading: Signal<boolean>;
26
- isSuccess: Signal<boolean>;
27
- isError: Signal<boolean>;
28
- isStale: Signal<boolean>;
29
- status: Signal<QueryState<T>["status"]>;
30
- /** Manually refetch the query. */
31
- refetch: () => Promise<void>;
32
- }
33
- /** Configuration for `useMutation`. */
34
- export interface UseMutationConfig<TData = unknown, TVariables = unknown> {
35
- mutationFn: (variables: TVariables) => Promise<FetchResult<TData>>;
36
- onSuccess?: (data: TData, variables: TVariables) => void;
37
- onError?: (error: ApiError, variables: TVariables) => void;
38
- onSettled?: (data: TData | null, error: ApiError | null, variables: TVariables) => void;
39
- }
40
- /** Reactive return value of `useMutation`. */
41
- export interface UseMutationReturn<TData = unknown, TVariables = unknown> {
42
- data: Signal<TData | null>;
43
- error: Signal<ApiError | null>;
44
- isLoading: Signal<boolean>;
45
- isSuccess: Signal<boolean>;
46
- isError: Signal<boolean>;
47
- status: Signal<"idle" | "loading" | "success" | "error">;
48
- /** Execute the mutation. */
49
- mutate: (variables: TVariables) => Promise<void>;
50
- /** Reset the mutation state. */
51
- reset: () => void;
17
+ /** Signal-based mutation result returned by {@link useMutation}. */
18
+ export interface AngularMutationResult<TData = unknown, TError = Error, TVariables = void> {
19
+ readonly data: Signal<TData | undefined>;
20
+ readonly error: Signal<TError | null>;
21
+ readonly variables: Signal<TVariables | undefined>;
22
+ readonly isPending: Signal<boolean>;
23
+ readonly isSuccess: Signal<boolean>;
24
+ readonly isError: Signal<boolean>;
25
+ readonly isIdle: Signal<boolean>;
26
+ readonly status: Signal<MutationStatus>;
27
+ readonly mutate: (variables: TVariables) => Promise<TData>;
28
+ readonly reset: () => void;
52
29
  }
53
30
  /**
54
- * Angular signal factory that wraps the {@link QueryClient}.
55
- * Integrates with the API manager — your `queryFn` typically calls `useGetApi`
56
- * or `useFetch` and returns the Safe Result.
31
+ * Angular signal factory for a cached query, backed by TanStack Query Core.
32
+ *
33
+ * Returns one signal per field — `query.data()`, `query.isPending()`,
34
+ * `query.isError()`, `query.status()`, etc.
57
35
  *
58
- * Must be called within an injection context (component field initializer,
59
- * constructor, or a service) so the returned query can auto-cleanup via
60
- * `DestroyRef`. Requires Angular 16+ signals.
36
+ * Must be called within an injection context (so it auto-cleans via `DestroyRef`).
61
37
  *
62
- * @param config - Query configuration.
63
- * @param client - Optional QueryClient instance (uses global singleton by default).
64
- * @returns Signals `{ data, error, isLoading, isSuccess, isError, isStale, status }` plus `refetch`.
38
+ * @param options - TanStack query options (`queryKey`, `queryFn`, `staleTime`, …).
39
+ * @param client - Optional {@link QueryClient} (defaults to the shared singleton).
40
+ * @returns An {@link AngularQueryResult} of signals.
65
41
  *
66
42
  * @example
67
43
  * ```ts
68
- * import { Component, inject } from "@angular/core";
69
- * import { useQuery } from "katanakit-js/adapters/angular";
44
+ * import { Component } from "@angular/core";
45
+ * import { useQuery, useSafeQueryFn } from "katanakit-js/adapters/angular";
70
46
  * import { useGetApi } from "katanakit-js";
71
47
  *
72
- * @Component({ selector: "app-pokemon", template: `@if (isLoading()) { Loading… } @else { {{ data()?.name }} }` })
48
+ * @Component({
49
+ * selector: "app-pokemon",
50
+ * template: `@if (query.isPending()) { Loading… } @else { {{ query.data()?.name }} }`,
51
+ * })
73
52
  * export class PokemonComponent {
74
- * readonly data = useQuery({ queryKey: ["pokemon", 25], queryFn: () => useGetApi("pokeapi", "pokemonById", { params: { id: 25 } }) }).data;
53
+ * readonly query = useQuery({
54
+ * queryKey: ["pokemon", 25],
55
+ * queryFn: useSafeQueryFn(() => useGetApi("pokeapi", "pokemonById", { params: { id: 25 } })),
56
+ * });
75
57
  * }
76
58
  * ```
77
59
  */
78
- export declare function useQuery<T>(config: UseQueryConfig<T>, client?: QueryClient): UseQueryReturn<T>;
60
+ export declare function useQuery<TQueryFnData = unknown, TError = Error, TData = TQueryFnData>(options: QueryObserverOptions<TQueryFnData, TError, TData>, client?: QueryClient): AngularQueryResult<TData, TError>;
79
61
  /**
80
- * Angular signal factory for mutations (POST/PUT/PATCH/DELETE).
81
- * Does not cache — returns a `mutate` function that executes the mutation.
62
+ * Angular signal factory for a mutation, backed by TanStack Query Core.
82
63
  *
83
- * Must be called within an injection context. Requires Angular 16+ signals.
64
+ * Must be called within an injection context (so it auto-cleans via `DestroyRef`).
84
65
  *
85
- * @param config - Mutation configuration.
86
- * @returns Signals plus `{ mutate, reset }`.
66
+ * @param options - TanStack mutation options (`mutationFn`, `onSuccess`, …).
67
+ * @param client - Optional {@link QueryClient} (defaults to the shared singleton).
68
+ * @returns An {@link AngularMutationResult} of signals.
87
69
  *
88
70
  * @example
89
71
  * ```ts
@@ -91,17 +73,18 @@ export declare function useQuery<T>(config: UseQueryConfig<T>, client?: QueryCli
91
73
  * import { useMutation, useQueryClient } from "katanakit-js/adapters/angular";
92
74
  * import { usePost } from "katanakit-js";
93
75
  *
94
- * @Component({ selector: "app-create", template: `<button [disabled]="isLoading()" (click)="mutate('Ada')">Create</button>` })
76
+ * @Component({
77
+ * selector: "app-create",
78
+ * template: `<button [disabled]="mutation.isPending()" (click)="mutation.mutate('Ada')">Create</button>`,
79
+ * })
95
80
  * export class CreateUserComponent {
96
81
  * private readonly qc = useQueryClient();
97
- * readonly result = useMutation({
82
+ * readonly mutation = useMutation({
98
83
  * mutationFn: (name: string) => usePost("api", "createUser", { name }),
99
84
  * onSuccess: () => this.qc.invalidateQueries({ queryKey: ["users"] }),
100
85
  * });
101
- * readonly isLoading = this.result.isLoading;
102
- * readonly mutate = this.result.mutate;
103
86
  * }
104
87
  * ```
105
88
  */
106
- export declare function useMutation<TData = unknown, TVariables = unknown>(config: UseMutationConfig<TData, TVariables>): UseMutationReturn<TData, TVariables>;
89
+ export declare function useMutation<TData = unknown, TError = Error, TVariables = void>(options: MutationObserverOptions<TData, TError, TVariables>, client?: QueryClient): AngularMutationResult<TData, TError, TVariables>;
107
90
  //# sourceMappingURL=query.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/adapters/angular/query.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/adapters/angular/query.ts"],"names":[],"mappings":"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"}