katanakit-js 3.2.2 → 4.0.0

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 (130) hide show
  1. package/README.md +142 -35
  2. package/dist/adapters/angular/fetch.d.ts +37 -0
  3. package/dist/adapters/angular/fetch.d.ts.map +1 -0
  4. package/dist/adapters/angular/fetch.js +67 -0
  5. package/dist/adapters/angular/fetch.js.map +1 -0
  6. package/dist/adapters/angular/index.d.ts +4 -0
  7. package/dist/adapters/angular/index.d.ts.map +1 -0
  8. package/dist/adapters/angular/index.js +4 -0
  9. package/dist/adapters/angular/index.js.map +1 -0
  10. package/dist/adapters/angular/query.d.ts +107 -0
  11. package/dist/adapters/angular/query.d.ts.map +1 -0
  12. package/dist/adapters/angular/query.js +166 -0
  13. package/dist/adapters/angular/query.js.map +1 -0
  14. package/dist/adapters/angular/watch.d.ts +34 -0
  15. package/dist/adapters/angular/watch.d.ts.map +1 -0
  16. package/dist/adapters/angular/watch.js +38 -0
  17. package/dist/adapters/angular/watch.js.map +1 -0
  18. package/dist/adapters/assistant/assistant.service.js +1 -1
  19. package/dist/adapters/assistant/assistant.service.js.map +1 -1
  20. package/dist/adapters/astro/astro.service.d.ts +0 -1
  21. package/dist/adapters/astro/astro.service.d.ts.map +1 -1
  22. package/dist/adapters/astro/astro.service.js +0 -1
  23. package/dist/adapters/astro/astro.service.js.map +1 -1
  24. package/dist/adapters/express/products.controller.d.ts.map +1 -1
  25. package/dist/adapters/express/products.controller.js +3 -1
  26. package/dist/adapters/express/products.controller.js.map +1 -1
  27. package/dist/adapters/notion/notion.service.d.ts +4 -2
  28. package/dist/adapters/notion/notion.service.d.ts.map +1 -1
  29. package/dist/adapters/notion/notion.service.js +19 -5
  30. package/dist/adapters/notion/notion.service.js.map +1 -1
  31. package/dist/adapters/react/fetch.d.ts +44 -0
  32. package/dist/adapters/react/fetch.d.ts.map +1 -0
  33. package/dist/adapters/react/fetch.js +74 -0
  34. package/dist/adapters/react/fetch.js.map +1 -0
  35. package/dist/adapters/react/index.d.ts +4 -0
  36. package/dist/adapters/react/index.d.ts.map +1 -0
  37. package/dist/adapters/react/index.js +4 -0
  38. package/dist/adapters/react/index.js.map +1 -0
  39. package/dist/adapters/react/query.d.ts +104 -0
  40. package/dist/adapters/react/query.d.ts.map +1 -0
  41. package/dist/adapters/react/query.js +200 -0
  42. package/dist/adapters/react/query.js.map +1 -0
  43. package/dist/adapters/react/watch.d.ts +37 -0
  44. package/dist/adapters/react/watch.d.ts.map +1 -0
  45. package/dist/adapters/react/watch.js +39 -0
  46. package/dist/adapters/react/watch.js.map +1 -0
  47. package/dist/adapters/solid/fetch.d.ts +43 -0
  48. package/dist/adapters/solid/fetch.d.ts.map +1 -0
  49. package/dist/adapters/solid/fetch.js +72 -0
  50. package/dist/adapters/solid/fetch.js.map +1 -0
  51. package/dist/adapters/solid/index.d.ts +4 -0
  52. package/dist/adapters/solid/index.d.ts.map +1 -0
  53. package/dist/adapters/solid/index.js +4 -0
  54. package/dist/adapters/solid/index.js.map +1 -0
  55. package/dist/adapters/solid/query.d.ts +102 -0
  56. package/dist/adapters/solid/query.d.ts.map +1 -0
  57. package/dist/adapters/solid/query.js +163 -0
  58. package/dist/adapters/solid/query.js.map +1 -0
  59. package/dist/adapters/solid/watch.d.ts +32 -0
  60. package/dist/adapters/solid/watch.d.ts.map +1 -0
  61. package/dist/adapters/solid/watch.js +36 -0
  62. package/dist/adapters/solid/watch.js.map +1 -0
  63. package/dist/adapters/svelte/fetch.d.ts +40 -0
  64. package/dist/adapters/svelte/fetch.d.ts.map +1 -0
  65. package/dist/adapters/svelte/fetch.js +75 -0
  66. package/dist/adapters/svelte/fetch.js.map +1 -0
  67. package/dist/adapters/svelte/index.d.ts +4 -0
  68. package/dist/adapters/svelte/index.d.ts.map +1 -0
  69. package/dist/adapters/svelte/index.js +4 -0
  70. package/dist/adapters/svelte/index.js.map +1 -0
  71. package/dist/adapters/svelte/query.d.ts +108 -0
  72. package/dist/adapters/svelte/query.d.ts.map +1 -0
  73. package/dist/adapters/svelte/query.js +172 -0
  74. package/dist/adapters/svelte/query.js.map +1 -0
  75. package/dist/adapters/svelte/watch.d.ts +32 -0
  76. package/dist/adapters/svelte/watch.d.ts.map +1 -0
  77. package/dist/adapters/svelte/watch.js +41 -0
  78. package/dist/adapters/svelte/watch.js.map +1 -0
  79. package/dist/adapters/vue/query.d.ts.map +1 -1
  80. package/dist/adapters/vue/query.js +8 -6
  81. package/dist/adapters/vue/query.js.map +1 -1
  82. package/dist/adapters/vue/vue.service.d.ts +9 -5
  83. package/dist/adapters/vue/vue.service.d.ts.map +1 -1
  84. package/dist/adapters/vue/vue.service.js +7 -3
  85. package/dist/adapters/vue/vue.service.js.map +1 -1
  86. package/dist/adapters/wordpress/wordpress.service.d.ts +2 -1
  87. package/dist/adapters/wordpress/wordpress.service.d.ts.map +1 -1
  88. package/dist/adapters/wordpress/wordpress.service.js +10 -5
  89. package/dist/adapters/wordpress/wordpress.service.js.map +1 -1
  90. package/dist/core/services/agent.service.d.ts.map +1 -1
  91. package/dist/core/services/agent.service.js +9 -1
  92. package/dist/core/services/agent.service.js.map +1 -1
  93. package/dist/core/services/dates.service.d.ts.map +1 -1
  94. package/dist/core/services/dates.service.js +2 -1
  95. package/dist/core/services/dates.service.js.map +1 -1
  96. package/dist/core/services/http.service.d.ts +26 -5
  97. package/dist/core/services/http.service.d.ts.map +1 -1
  98. package/dist/core/services/http.service.js +30 -6
  99. package/dist/core/services/http.service.js.map +1 -1
  100. package/dist/core/services/query.service.d.ts +4 -0
  101. package/dist/core/services/query.service.d.ts.map +1 -1
  102. package/dist/core/services/query.service.js +66 -55
  103. package/dist/core/services/query.service.js.map +1 -1
  104. package/dist/core/services/reactive.service.d.ts.map +1 -1
  105. package/dist/core/services/reactive.service.js +0 -3
  106. package/dist/core/services/reactive.service.js.map +1 -1
  107. package/dist/core/services/utils.service.d.ts.map +1 -1
  108. package/dist/core/services/utils.service.js +3 -0
  109. package/dist/core/services/utils.service.js.map +1 -1
  110. package/dist/infrastructure/dom/dom.service.d.ts.map +1 -1
  111. package/dist/infrastructure/dom/dom.service.js +15 -3
  112. package/dist/infrastructure/dom/dom.service.js.map +1 -1
  113. package/dist/infrastructure/storage/storage.service.d.ts.map +1 -1
  114. package/dist/infrastructure/storage/storage.service.js +12 -2
  115. package/dist/infrastructure/storage/storage.service.js.map +1 -1
  116. package/dist/prisma/assistant.store.d.ts +3 -0
  117. package/dist/prisma/assistant.store.d.ts.map +1 -1
  118. package/dist/prisma/assistant.store.js +12 -6
  119. package/dist/prisma/assistant.store.js.map +1 -1
  120. package/dist/prisma/use-prisma.d.ts +5 -4
  121. package/dist/prisma/use-prisma.d.ts.map +1 -1
  122. package/dist/prisma/use-prisma.js +5 -4
  123. package/dist/prisma/use-prisma.js.map +1 -1
  124. package/dist/types/index.d.ts +0 -1
  125. package/dist/types/index.d.ts.map +1 -1
  126. package/package.json +249 -185
  127. package/dist/prisma/db.d.ts +0 -4
  128. package/dist/prisma/db.d.ts.map +0 -1
  129. package/dist/prisma/db.js +0 -12
  130. package/dist/prisma/db.js.map +0 -1
@@ -0,0 +1,74 @@
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
+ import { useFetch } from "../../core/services/http.service.js";
3
+ /**
4
+ * React hook that wraps KatanaKit's HTTP GET with `useState` reactivity.
5
+ * Bridges the Safe Result pattern to idiomatic React state and never throws
6
+ * on HTTP errors.
7
+ *
8
+ * Stale responses are ignored via a request version counter and AbortController;
9
+ * in-flight requests are aborted on unmount. Re-fetches automatically when the
10
+ * serialized `options` change.
11
+ *
12
+ * @param apiName - Name of the registered API (see `useInitApis`).
13
+ * @param endpointName - Name of the endpoint inside that API.
14
+ * @param options - Optional `UrlOptions` (path/query params).
15
+ * @returns `{ data, error, loading, refetch }`.
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * import { useRequest } from "katanakit-js/adapters/react";
20
+ *
21
+ * function Pokemon({ id }: { id: number }) {
22
+ * const { data, error, loading } = useRequest<{ name: string }>(
23
+ * "pokeapi",
24
+ * "pokemonById",
25
+ * { params: { id } },
26
+ * );
27
+ * if (loading) return <div>Loading…</div>;
28
+ * if (error) return <div>{error.message}</div>;
29
+ * return <div>{data?.name}</div>;
30
+ * }
31
+ * ```
32
+ */
33
+ export function useRequest(apiName, endpointName, options) {
34
+ const [data, setData] = useState(null);
35
+ const [error, setError] = useState(null);
36
+ const [loading, setLoading] = useState(true);
37
+ const versionRef = useRef(0);
38
+ const controllerRef = useRef(null);
39
+ const mountedRef = useRef(true);
40
+ const optionsKey = JSON.stringify(options ?? null);
41
+ const refetch = useCallback(async () => {
42
+ const version = ++versionRef.current;
43
+ controllerRef.current?.abort();
44
+ const controller = new AbortController();
45
+ controllerRef.current = controller;
46
+ setLoading(true);
47
+ setError(null);
48
+ const result = await useFetch(apiName, endpointName, {
49
+ method: "GET",
50
+ urlOptions: options,
51
+ signal: controller.signal,
52
+ });
53
+ if (!mountedRef.current || version !== versionRef.current)
54
+ return;
55
+ if (result.ok) {
56
+ setData(result.data);
57
+ setError(null);
58
+ }
59
+ else if (!controller.signal.aborted) {
60
+ setError(result.error);
61
+ }
62
+ setLoading(false);
63
+ }, [apiName, endpointName, optionsKey]);
64
+ useEffect(() => {
65
+ mountedRef.current = true;
66
+ void refetch();
67
+ return () => {
68
+ mountedRef.current = false;
69
+ controllerRef.current?.abort();
70
+ };
71
+ }, [refetch]);
72
+ return { data, error, loading, refetch };
73
+ }
74
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../../src/adapters/react/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjE,OAAO,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAe/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,UAAU,CACzB,OAAe,EACf,YAAoB,EACpB,OAAoB;IAEpB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAW,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAkB,IAAI,CAAC,CAAC;IAC1D,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE7C,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,aAAa,GAAG,MAAM,CAAyB,IAAI,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAEhC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;IAEnD,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,IAAmB,EAAE;QACrD,MAAM,OAAO,GAAG,EAAE,UAAU,CAAC,OAAO,CAAC;QACrC,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,aAAa,CAAC,OAAO,GAAG,UAAU,CAAC;QAEnC,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEf,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAI,OAAO,EAAE,YAAY,EAAE;YACvD,MAAM,EAAE,KAAK;YACb,UAAU,EAAE,OAAO;YACnB,MAAM,EAAE,UAAU,CAAC,MAAM;SACzB,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,CAAC,OAAO,IAAI,OAAO,KAAK,UAAU,CAAC,OAAO;YAAE,OAAO;QAElE,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACrB,QAAQ,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;aAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACvC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;QACD,UAAU,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;IAExC,SAAS,CAAC,GAAG,EAAE;QACd,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;QAC1B,KAAK,OAAO,EAAE,CAAC;QACf,OAAO,GAAG,EAAE;YACX,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC;YAC3B,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QAChC,CAAC,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./fetch.js";
2
+ export * from "./query.js";
3
+ export * from "./watch.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/react/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./fetch.js";
2
+ export * from "./query.js";
3
+ export * from "./watch.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/react/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,104 @@
1
+ import { type QueryClient, type QueryKey, type QueryState } from "../../core/services/query.service.js";
2
+ import type { ApiError, FetchResult } from "../../types/index.js";
3
+ /** Configuration for `useQuery` (React hook). */
4
+ export interface UseQueryConfig<T = unknown> {
5
+ /** Cache key — the query refetches when its serialized value changes. */
6
+ queryKey: QueryKey;
7
+ /** Fetcher function returning a Safe Result. */
8
+ queryFn: () => Promise<FetchResult<T>>;
9
+ /** Time in ms before cached data is stale (default: 0). */
10
+ staleTime?: number;
11
+ /** Time in ms to keep unused data (default: 5 min). */
12
+ cacheTime?: number;
13
+ /** Retry count on failure (default: 3). */
14
+ retry?: number;
15
+ /** Base delay for exponential backoff (default: 1000). */
16
+ retryDelay?: number;
17
+ /** Whether the query is enabled (default: true). */
18
+ enabled?: boolean;
19
+ }
20
+ /** Reactive return value of `useQuery`. */
21
+ export interface UseQueryReturn<T = unknown> {
22
+ data: T | null;
23
+ error: ApiError | null;
24
+ isLoading: boolean;
25
+ isSuccess: boolean;
26
+ isError: boolean;
27
+ isStale: boolean;
28
+ status: QueryState<T>["status"];
29
+ /** Manually refetch the query. */
30
+ refetch: () => Promise<void>;
31
+ }
32
+ /** Configuration for `useMutation`. */
33
+ export interface UseMutationConfig<TData = unknown, TVariables = unknown> {
34
+ mutationFn: (variables: TVariables) => Promise<FetchResult<TData>>;
35
+ onSuccess?: (data: TData, variables: TVariables) => void;
36
+ onError?: (error: ApiError, variables: TVariables) => void;
37
+ onSettled?: (data: TData | null, error: ApiError | null, variables: TVariables) => void;
38
+ }
39
+ /** Reactive return value of `useMutation`. */
40
+ export interface UseMutationReturn<TData = unknown, TVariables = unknown> {
41
+ data: TData | null;
42
+ error: ApiError | null;
43
+ isLoading: boolean;
44
+ isSuccess: boolean;
45
+ isError: boolean;
46
+ status: "idle" | "loading" | "success" | "error";
47
+ /** Execute the mutation. */
48
+ mutate: (variables: TVariables) => Promise<void>;
49
+ /** Reset the mutation state. */
50
+ reset: () => void;
51
+ }
52
+ /**
53
+ * React hook that wraps the {@link QueryClient} with `useState` reactivity.
54
+ * Integrates with the API manager — your `queryFn` typically calls `useGetApi`
55
+ * or `useFetch` and returns the Safe Result.
56
+ *
57
+ * Subscribes to the global query cache, refetches when the serialized
58
+ * `queryKey` changes, and unsubscribes on unmount.
59
+ *
60
+ * @param config - Query configuration.
61
+ * @param client - Optional QueryClient instance (uses global singleton by default).
62
+ * @returns `{ data, error, isLoading, isSuccess, isError, isStale, status, refetch }`.
63
+ *
64
+ * @example
65
+ * ```tsx
66
+ * import { useQuery } from "katanakit-js/adapters/react";
67
+ * import { useGetApi } from "katanakit-js";
68
+ *
69
+ * function Pokemon({ id }: { id: number }) {
70
+ * const { data, isLoading, error } = useQuery({
71
+ * queryKey: ["pokemon", id],
72
+ * queryFn: () => useGetApi("pokeapi", "pokemonById", { params: { id } }),
73
+ * });
74
+ * if (isLoading) return <div>Loading…</div>;
75
+ * if (error) return <div>{error.message}</div>;
76
+ * return <div>{data?.name}</div>;
77
+ * }
78
+ * ```
79
+ */
80
+ export declare function useQuery<T>(config: UseQueryConfig<T>, client?: QueryClient): UseQueryReturn<T>;
81
+ /**
82
+ * React hook for mutations (POST/PUT/PATCH/DELETE).
83
+ * Does not cache — returns a `mutate` function that executes the mutation.
84
+ *
85
+ * @param config - Mutation configuration.
86
+ * @returns `{ data, error, isLoading, isSuccess, isError, status, mutate, reset }`.
87
+ *
88
+ * @example
89
+ * ```tsx
90
+ * import { useMutation, useQueryClient } from "katanakit-js/adapters/react";
91
+ * import { usePost } from "katanakit-js";
92
+ *
93
+ * function CreateUser() {
94
+ * const qc = useQueryClient();
95
+ * const { mutate, isLoading } = useMutation({
96
+ * mutationFn: (name: string) => usePost("api", "createUser", { name }),
97
+ * onSuccess: () => qc.invalidateQueries({ queryKey: ["users"] }),
98
+ * });
99
+ * return <button disabled={isLoading} onClick={() => mutate("Ada")}>Create</button>;
100
+ * }
101
+ * ```
102
+ */
103
+ export declare function useMutation<TData = unknown, TVariables = unknown>(config: UseMutationConfig<TData, TVariables>): UseMutationReturn<TData, TVariables>;
104
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/adapters/react/query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,200 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+ import { useQueryClient, } from "../../core/services/query.service.js";
3
+ const IDLE_STATE = {
4
+ status: "idle",
5
+ data: null,
6
+ error: null,
7
+ isLoading: false,
8
+ isSuccess: false,
9
+ isError: false,
10
+ isStale: true,
11
+ dataUpdatedAt: 0,
12
+ errorUpdatedAt: 0,
13
+ fetchCount: 0,
14
+ };
15
+ /**
16
+ * React hook that wraps the {@link QueryClient} with `useState` reactivity.
17
+ * Integrates with the API manager — your `queryFn` typically calls `useGetApi`
18
+ * or `useFetch` and returns the Safe Result.
19
+ *
20
+ * Subscribes to the global query cache, refetches when the serialized
21
+ * `queryKey` changes, and unsubscribes on unmount.
22
+ *
23
+ * @param config - Query configuration.
24
+ * @param client - Optional QueryClient instance (uses global singleton by default).
25
+ * @returns `{ data, error, isLoading, isSuccess, isError, isStale, status, refetch }`.
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * import { useQuery } from "katanakit-js/adapters/react";
30
+ * import { useGetApi } from "katanakit-js";
31
+ *
32
+ * function Pokemon({ id }: { id: number }) {
33
+ * const { data, isLoading, error } = useQuery({
34
+ * queryKey: ["pokemon", id],
35
+ * queryFn: () => useGetApi("pokeapi", "pokemonById", { params: { id } }),
36
+ * });
37
+ * if (isLoading) return <div>Loading…</div>;
38
+ * if (error) return <div>{error.message}</div>;
39
+ * return <div>{data?.name}</div>;
40
+ * }
41
+ * ```
42
+ */
43
+ export function useQuery(config, client) {
44
+ const qc = client ?? useQueryClient();
45
+ const [state, setState] = useState(IDLE_STATE);
46
+ // Serialize the key so React's dependency comparison tracks deep changes.
47
+ const keyHash = JSON.stringify(config.queryKey);
48
+ useEffect(() => {
49
+ let disposed = false;
50
+ const qKey = config.queryKey;
51
+ setState(IDLE_STATE);
52
+ const unsubscribe = qc.subscribe(qKey, (next) => {
53
+ if (!disposed)
54
+ setState(next);
55
+ });
56
+ const existing = qc.getQueryState(qKey);
57
+ if (existing)
58
+ setState(existing);
59
+ if (config.enabled !== false) {
60
+ void qc
61
+ .fetchQuery({
62
+ queryKey: qKey,
63
+ queryFn: config.queryFn,
64
+ staleTime: config.staleTime,
65
+ cacheTime: config.cacheTime,
66
+ retry: config.retry,
67
+ retryDelay: config.retryDelay,
68
+ })
69
+ .catch(() => {
70
+ // Error is already reflected in the cache state.
71
+ });
72
+ }
73
+ return () => {
74
+ disposed = true;
75
+ unsubscribe();
76
+ };
77
+ }, [keyHash, config.enabled]);
78
+ const refetch = useCallback(async () => {
79
+ await qc
80
+ .fetchQuery({
81
+ queryKey: config.queryKey,
82
+ queryFn: config.queryFn,
83
+ staleTime: 0,
84
+ cacheTime: config.cacheTime,
85
+ retry: config.retry,
86
+ retryDelay: config.retryDelay,
87
+ })
88
+ .catch(() => {
89
+ // Error is already reflected in the cache state.
90
+ });
91
+ }, [qc, keyHash]);
92
+ return {
93
+ data: state.data,
94
+ error: state.error,
95
+ isLoading: state.isLoading,
96
+ isSuccess: state.isSuccess,
97
+ isError: state.isError,
98
+ isStale: state.isStale,
99
+ status: state.status,
100
+ refetch,
101
+ };
102
+ }
103
+ const IDLE_MUTATION_STATE = {
104
+ data: null,
105
+ error: null,
106
+ isLoading: false,
107
+ isSuccess: false,
108
+ isError: false,
109
+ status: "idle",
110
+ };
111
+ /**
112
+ * React hook for mutations (POST/PUT/PATCH/DELETE).
113
+ * Does not cache — returns a `mutate` function that executes the mutation.
114
+ *
115
+ * @param config - Mutation configuration.
116
+ * @returns `{ data, error, isLoading, isSuccess, isError, status, mutate, reset }`.
117
+ *
118
+ * @example
119
+ * ```tsx
120
+ * import { useMutation, useQueryClient } from "katanakit-js/adapters/react";
121
+ * import { usePost } from "katanakit-js";
122
+ *
123
+ * function CreateUser() {
124
+ * const qc = useQueryClient();
125
+ * const { mutate, isLoading } = useMutation({
126
+ * mutationFn: (name: string) => usePost("api", "createUser", { name }),
127
+ * onSuccess: () => qc.invalidateQueries({ queryKey: ["users"] }),
128
+ * });
129
+ * return <button disabled={isLoading} onClick={() => mutate("Ada")}>Create</button>;
130
+ * }
131
+ * ```
132
+ */
133
+ export function useMutation(config) {
134
+ const [state, setState] = useState(IDLE_MUTATION_STATE);
135
+ const mutate = useCallback(async (variables) => {
136
+ setState((prev) => ({
137
+ ...prev,
138
+ isLoading: true,
139
+ isSuccess: false,
140
+ isError: false,
141
+ status: "loading",
142
+ }));
143
+ try {
144
+ const result = await config.mutationFn(variables);
145
+ if (result.ok) {
146
+ setState({
147
+ data: result.data,
148
+ error: null,
149
+ isLoading: false,
150
+ isSuccess: true,
151
+ isError: false,
152
+ status: "success",
153
+ });
154
+ config.onSuccess?.(result.data, variables);
155
+ config.onSettled?.(result.data, null, variables);
156
+ }
157
+ else {
158
+ setState({
159
+ data: null,
160
+ error: result.error,
161
+ isLoading: false,
162
+ isSuccess: false,
163
+ isError: true,
164
+ status: "error",
165
+ });
166
+ config.onError?.(result.error, variables);
167
+ config.onSettled?.(null, result.error, variables);
168
+ }
169
+ }
170
+ catch (error) {
171
+ const apiError = error instanceof Error
172
+ ? { message: error.message, status: 0 }
173
+ : { message: String(error), status: 0 };
174
+ setState({
175
+ data: null,
176
+ error: apiError,
177
+ isLoading: false,
178
+ isSuccess: false,
179
+ isError: true,
180
+ status: "error",
181
+ });
182
+ config.onError?.(apiError, variables);
183
+ config.onSettled?.(null, apiError, variables);
184
+ }
185
+ }, []);
186
+ const reset = useCallback(() => {
187
+ setState(IDLE_MUTATION_STATE);
188
+ }, []);
189
+ return {
190
+ data: state.data,
191
+ error: state.error,
192
+ isLoading: state.isLoading,
193
+ isSuccess: state.isSuccess,
194
+ isError: state.isError,
195
+ status: state.status,
196
+ mutate,
197
+ reset,
198
+ };
199
+ }
200
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/adapters/react/query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /** Options for {@link useWatch}. */
2
+ export interface UseWatchOptions {
3
+ /**
4
+ * Compare values deeply (via JSON serialization) instead of by reference.
5
+ * Defaults to `true`, matching the Vue adapter.
6
+ */
7
+ deep?: boolean;
8
+ }
9
+ /**
10
+ * React effect-based watcher that invokes `callback` whenever the value
11
+ * produced by `source` changes. Tracks the previous value so the callback
12
+ * receives `(value, previous)`.
13
+ *
14
+ * Runs once on mount (with `previous` undefined) and on every change. Cleans
15
+ * up automatically on unmount.
16
+ *
17
+ * @typeParam T - The watched value type.
18
+ * @param source - A getter returning the value to watch.
19
+ * @param callback - Invoked on change as `(value, previous)`.
20
+ * @param options - `deep` (default `true`) serializes objects for comparison.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * import { useState } from "react";
25
+ * import { useWatch } from "katanakit-js/adapters/react";
26
+ *
27
+ * function Form() {
28
+ * const [product, setProduct] = useState({ name: "", price: 0 });
29
+ * useWatch(() => product, (next, prev) => {
30
+ * console.log("changed:", next, prev);
31
+ * });
32
+ * // ...
33
+ * }
34
+ * ```
35
+ */
36
+ export declare function useWatch<T>(source: () => T, callback: (value: T, previous: T | undefined) => void, options?: UseWatchOptions): void;
37
+ //# sourceMappingURL=watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../../src/adapters/react/watch.ts"],"names":[],"mappings":"AAEA,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC/B;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACzB,MAAM,EAAE,MAAM,CAAC,EACf,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,SAAS,KAAK,IAAI,EACrD,OAAO,GAAE,eAAoB,GAC3B,IAAI,CAUN"}
@@ -0,0 +1,39 @@
1
+ import { useEffect, useRef } from "react";
2
+ /**
3
+ * React effect-based watcher that invokes `callback` whenever the value
4
+ * produced by `source` changes. Tracks the previous value so the callback
5
+ * receives `(value, previous)`.
6
+ *
7
+ * Runs once on mount (with `previous` undefined) and on every change. Cleans
8
+ * up automatically on unmount.
9
+ *
10
+ * @typeParam T - The watched value type.
11
+ * @param source - A getter returning the value to watch.
12
+ * @param callback - Invoked on change as `(value, previous)`.
13
+ * @param options - `deep` (default `true`) serializes objects for comparison.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * import { useState } from "react";
18
+ * import { useWatch } from "katanakit-js/adapters/react";
19
+ *
20
+ * function Form() {
21
+ * const [product, setProduct] = useState({ name: "", price: 0 });
22
+ * useWatch(() => product, (next, prev) => {
23
+ * console.log("changed:", next, prev);
24
+ * });
25
+ * // ...
26
+ * }
27
+ * ```
28
+ */
29
+ export function useWatch(source, callback, options = {}) {
30
+ const { deep = true } = options;
31
+ const previous = useRef(undefined);
32
+ const current = source();
33
+ const dep = deep ? JSON.stringify(current) : current;
34
+ useEffect(() => {
35
+ callback(current, previous.current);
36
+ previous.current = current;
37
+ }, [dep]);
38
+ }
39
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../../src/adapters/react/watch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAW1C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,QAAQ,CACvB,MAAe,EACf,QAAqD,EACrD,UAA2B,EAAE;IAE7B,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAChC,MAAM,QAAQ,GAAG,MAAM,CAAgB,SAAS,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC;IACzB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAErD,SAAS,CAAC,GAAG,EAAE;QACd,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpC,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC;IAC5B,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { type Signal } from "solid-js";
2
+ import type { ApiError, UrlOptions } from "../../types/index.js";
3
+ /** Reactive state exposed by the {@link useRequest} primitive (Solid accessors). */
4
+ export interface RequestState<T = unknown> {
5
+ data: Signal<T | null>[0];
6
+ error: Signal<ApiError | null>[0];
7
+ loading: Signal<boolean>[0];
8
+ refetch: () => Promise<void>;
9
+ }
10
+ /**
11
+ * Solid primitive that wraps KatanaKit's HTTP GET with fine-grained signals.
12
+ * Bridges the Safe Result pattern to idiomatic Solid state and never throws
13
+ * on HTTP errors.
14
+ *
15
+ * Stale responses are ignored via a request version counter and AbortController;
16
+ * in-flight requests are aborted on cleanup.
17
+ *
18
+ * @param apiName - Name of the registered API (see `useInitApis`).
19
+ * @param endpointName - Name of the endpoint inside that API.
20
+ * @param options - Optional `UrlOptions` (path/query params).
21
+ * @returns Signal accessors `{ data, error, loading }` plus `refetch`.
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * import { Show } from "solid-js";
26
+ * import { useRequest } from "katanakit-js/adapters/solid";
27
+ *
28
+ * function Pokemon() {
29
+ * const { data, error, loading } = useRequest<{ name: string }>(
30
+ * "pokeapi",
31
+ * "pokemonById",
32
+ * { params: { id: 25 } },
33
+ * );
34
+ * return (
35
+ * <Show when={!loading() && !error()} fallback={<div>Loading…</div>}>
36
+ * <div>{data()?.name}</div>
37
+ * </Show>
38
+ * );
39
+ * }
40
+ * ```
41
+ */
42
+ export declare function useRequest<T>(apiName: string, endpointName: string, options?: UrlOptions): RequestState<T>;
43
+ //# sourceMappingURL=fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../src/adapters/solid/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAGhE,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEjE,oFAAoF;AACpF,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO;IACxC,IAAI,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAC3B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,UAAU,GAClB,YAAY,CAAC,CAAC,CAAC,CA2CjB"}
@@ -0,0 +1,72 @@
1
+ import { createSignal, onCleanup } from "solid-js";
2
+ import { useFetch } from "../../core/services/http.service.js";
3
+ /**
4
+ * Solid primitive that wraps KatanaKit's HTTP GET with fine-grained signals.
5
+ * Bridges the Safe Result pattern to idiomatic Solid state and never throws
6
+ * on HTTP errors.
7
+ *
8
+ * Stale responses are ignored via a request version counter and AbortController;
9
+ * in-flight requests are aborted on cleanup.
10
+ *
11
+ * @param apiName - Name of the registered API (see `useInitApis`).
12
+ * @param endpointName - Name of the endpoint inside that API.
13
+ * @param options - Optional `UrlOptions` (path/query params).
14
+ * @returns Signal accessors `{ data, error, loading }` plus `refetch`.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * import { Show } from "solid-js";
19
+ * import { useRequest } from "katanakit-js/adapters/solid";
20
+ *
21
+ * function Pokemon() {
22
+ * const { data, error, loading } = useRequest<{ name: string }>(
23
+ * "pokeapi",
24
+ * "pokemonById",
25
+ * { params: { id: 25 } },
26
+ * );
27
+ * return (
28
+ * <Show when={!loading() && !error()} fallback={<div>Loading…</div>}>
29
+ * <div>{data()?.name}</div>
30
+ * </Show>
31
+ * );
32
+ * }
33
+ * ```
34
+ */
35
+ export function useRequest(apiName, endpointName, options) {
36
+ const [data, setData] = createSignal(null);
37
+ const [error, setError] = createSignal(null);
38
+ const [loading, setLoading] = createSignal(true);
39
+ let version = 0;
40
+ let controller = null;
41
+ let disposed = false;
42
+ const refetch = async () => {
43
+ const current = ++version;
44
+ controller?.abort();
45
+ const next = new AbortController();
46
+ controller = next;
47
+ setLoading(true);
48
+ setError(null);
49
+ const result = await useFetch(apiName, endpointName, {
50
+ method: "GET",
51
+ urlOptions: options,
52
+ signal: next.signal,
53
+ });
54
+ if (disposed || current !== version)
55
+ return;
56
+ if (result.ok) {
57
+ setData(() => result.data);
58
+ setError(null);
59
+ }
60
+ else if (!next.signal.aborted) {
61
+ setError(result.error);
62
+ }
63
+ setLoading(false);
64
+ };
65
+ onCleanup(() => {
66
+ disposed = true;
67
+ controller?.abort();
68
+ });
69
+ void refetch();
70
+ return { data, error, loading, refetch };
71
+ }
72
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../../src/adapters/solid/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAe,MAAM,UAAU,CAAC;AAEhE,OAAO,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAW/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,UAAU,CACzB,OAAe,EACf,YAAoB,EACpB,OAAoB;IAEpB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,YAAY,CAAW,IAAI,CAAC,CAAC;IACrD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAkB,IAAI,CAAC,CAAC;IAC9D,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAEjD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,UAAU,GAA2B,IAAI,CAAC;IAC9C,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,MAAM,OAAO,GAAG,KAAK,IAAmB,EAAE;QACzC,MAAM,OAAO,GAAG,EAAE,OAAO,CAAC;QAC1B,UAAU,EAAE,KAAK,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,IAAI,eAAe,EAAE,CAAC;QACnC,UAAU,GAAG,IAAI,CAAC;QAElB,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEf,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAI,OAAO,EAAE,YAAY,EAAE;YACvD,MAAM,EAAE,KAAK;YACb,UAAU,EAAE,OAAO;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;SACnB,CAAC,CAAC;QAEH,IAAI,QAAQ,IAAI,OAAO,KAAK,OAAO;YAAE,OAAO;QAE5C,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC3B,QAAQ,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;aAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACjC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;QACD,UAAU,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACd,QAAQ,GAAG,IAAI,CAAC;QAChB,UAAU,EAAE,KAAK,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,KAAK,OAAO,EAAE,CAAC;IAEf,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./fetch.js";
2
+ export * from "./query.js";
3
+ export * from "./watch.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/solid/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./fetch.js";
2
+ export * from "./query.js";
3
+ export * from "./watch.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/solid/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}