@plasius/react-query 1.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 (50) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/CODE_OF_CONDUCT.md +79 -0
  3. package/CONTRIBUTORS.md +27 -0
  4. package/LICENSE +21 -0
  5. package/README.md +43 -0
  6. package/SECURITY.md +17 -0
  7. package/dist/globalCache.d.ts +11 -0
  8. package/dist/globalCache.d.ts.map +1 -0
  9. package/dist/globalCache.js +39 -0
  10. package/dist/index.d.ts +4 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +3 -0
  13. package/dist/useMutation.d.ts +18 -0
  14. package/dist/useMutation.d.ts.map +1 -0
  15. package/dist/useMutation.js +49 -0
  16. package/dist/useQuery.d.ts +9 -0
  17. package/dist/useQuery.d.ts.map +1 -0
  18. package/dist/useQuery.js +38 -0
  19. package/dist/useQueryClient.d.ts +7 -0
  20. package/dist/useQueryClient.d.ts.map +1 -0
  21. package/dist/useQueryClient.js +25 -0
  22. package/dist-cjs/globalCache.d.ts +11 -0
  23. package/dist-cjs/globalCache.d.ts.map +1 -0
  24. package/dist-cjs/globalCache.js +46 -0
  25. package/dist-cjs/index.d.ts +4 -0
  26. package/dist-cjs/index.d.ts.map +1 -0
  27. package/dist-cjs/index.js +19 -0
  28. package/dist-cjs/useMutation.d.ts +18 -0
  29. package/dist-cjs/useMutation.d.ts.map +1 -0
  30. package/dist-cjs/useMutation.js +52 -0
  31. package/dist-cjs/useQuery.d.ts +9 -0
  32. package/dist-cjs/useQuery.d.ts.map +1 -0
  33. package/dist-cjs/useQuery.js +41 -0
  34. package/dist-cjs/useQueryClient.d.ts +7 -0
  35. package/dist-cjs/useQueryClient.d.ts.map +1 -0
  36. package/dist-cjs/useQueryClient.js +28 -0
  37. package/docs/adrs/adr-0001-react-query-package-scope.md +21 -0
  38. package/docs/adrs/adr-0002-public-repo-governance.md +24 -0
  39. package/docs/adrs/adr-template.md +35 -0
  40. package/docs/how-to-use.md +91 -0
  41. package/legal/CLA-REGISTRY.csv +1 -0
  42. package/legal/CLA.md +22 -0
  43. package/legal/CORPORATE_CLA.md +57 -0
  44. package/legal/INDIVIDUAL_CLA.md +91 -0
  45. package/package.json +102 -0
  46. package/src/globalCache.ts +54 -0
  47. package/src/index.ts +3 -0
  48. package/src/useMutation.ts +87 -0
  49. package/src/useQuery.ts +60 -0
  50. package/src/useQueryClient.ts +29 -0
@@ -0,0 +1,87 @@
1
+
2
+
3
+ import { useState, useCallback } from "react";
4
+
5
+ interface UseMutationOptions<TData, TError, TVariables, TContext = unknown> {
6
+ onMutate?: (variables: TVariables) => Promise<TContext> | TContext | void;
7
+ onSuccess?: (
8
+ data: TData,
9
+ variables: TVariables,
10
+ context: TContext | undefined
11
+ ) => void;
12
+ onError?: (
13
+ error: TError,
14
+ variables: TVariables,
15
+ context: TContext | undefined
16
+ ) => void;
17
+ onSettled?: (
18
+ data: TData | undefined,
19
+ error: TError | undefined,
20
+ variables: TVariables | undefined,
21
+ context: TContext | undefined
22
+ ) => void;
23
+ }
24
+
25
+ interface UseMutationResult<TData, TError, TVariables, TContext = unknown> {
26
+ mutate: (variables: TVariables) => void;
27
+ mutateAsync: (variables: TVariables) => Promise<TData>;
28
+ reset: () => void;
29
+ data: TData | undefined;
30
+ error: TError | undefined;
31
+ isLoading: boolean;
32
+ context: TContext | undefined;
33
+ }
34
+
35
+ export function useMutation<TData, TError = unknown, TVariables = void, TContext = unknown>(
36
+ mutationFn: (variables: TVariables) => Promise<TData>,
37
+ options?: UseMutationOptions<TData, TError, TVariables, TContext>
38
+ ): UseMutationResult<TData, TError, TVariables, TContext> {
39
+ const [data, setData] = useState<TData>();
40
+ const [error, setError] = useState<TError>();
41
+ const [isLoading, setIsLoading] = useState(false);
42
+ const [context, setContext] = useState<TContext | undefined>(undefined);
43
+
44
+ const mutateAsync = useCallback(async (variables: TVariables): Promise<TData> => {
45
+ setIsLoading(true);
46
+ setError(undefined);
47
+ try {
48
+ if (options?.onMutate) {
49
+ setContext((await options.onMutate(variables)) as TContext | undefined);
50
+ }
51
+ const result = await mutationFn(variables);
52
+ setData(result);
53
+ options?.onSuccess?.(result, variables, context);
54
+ options?.onSettled?.(result, undefined, variables, context);
55
+ return result;
56
+ } catch (err) {
57
+ const typedErr = err as TError;
58
+ setError(typedErr);
59
+ options?.onError?.(typedErr, variables, context);
60
+ options?.onSettled?.(undefined, typedErr, variables, context);
61
+ throw typedErr as Error;
62
+ } finally {
63
+ setIsLoading(false);
64
+ }
65
+ }, [mutationFn, options]);
66
+
67
+ const mutate = useCallback((variables: TVariables) => {
68
+ void mutateAsync(variables);
69
+ }, [mutateAsync]);
70
+
71
+ const reset = useCallback(() => {
72
+ setData(undefined);
73
+ setError(undefined);
74
+ setIsLoading(false);
75
+ setContext(undefined);
76
+ }, []);
77
+
78
+ return {
79
+ mutate,
80
+ mutateAsync,
81
+ reset,
82
+ data,
83
+ error,
84
+ isLoading,
85
+ context
86
+ };
87
+ }
@@ -0,0 +1,60 @@
1
+
2
+
3
+ import { useEffect, useState, useCallback } from "react";
4
+ import {
5
+ getCache,
6
+ setCache,
7
+ setCacheError,
8
+ subscribe,
9
+ unsubscribe,
10
+ } from "./globalCache.js";
11
+
12
+ interface UseQueryResult<T> {
13
+ data: T | undefined;
14
+ error: unknown;
15
+ isLoading: boolean;
16
+ refetch: () => void;
17
+ }
18
+
19
+ export function useQuery<T>(key: string, fetcher: () => Promise<T>): UseQueryResult<T> {
20
+ const cached = getCache<T>(key);
21
+ const [data, setData] = useState<T | undefined>(cached.data);
22
+ const [error, setError] = useState<unknown>(cached.error);
23
+ const [isLoading, setIsLoading] = useState(!cached.data && !cached.error);
24
+
25
+ const load = useCallback(() => {
26
+ setIsLoading(true);
27
+ fetcher()
28
+ .then((result) => {
29
+ setCache(key, result);
30
+ })
31
+ .catch((err) => {
32
+ setCacheError(key, err);
33
+ });
34
+ }, [key, fetcher]);
35
+
36
+ useEffect(() => {
37
+ const listener = (data: T | undefined, error: unknown) => {
38
+ setData(data);
39
+ setError(error);
40
+ setIsLoading(false);
41
+ };
42
+
43
+ subscribe<T>(key, listener);
44
+
45
+ if (!cached.data && !cached.error) {
46
+ load();
47
+ }
48
+
49
+ return () => {
50
+ unsubscribe<T>(key, listener);
51
+ };
52
+ }, [key, cached.data, cached.error, load]);
53
+
54
+ return {
55
+ data,
56
+ error,
57
+ isLoading,
58
+ refetch: load,
59
+ };
60
+ }
@@ -0,0 +1,29 @@
1
+ import {
2
+ getCache,
3
+ setCache,
4
+ setCacheError,
5
+ } from "./globalCache.js";
6
+
7
+ export function useQueryClient() {
8
+ return {
9
+ getQueryData: <T>(key: string): T | undefined => {
10
+ const { data } = getCache<T>(key);
11
+ return data;
12
+ },
13
+ setQueryData: <T>(key: string, data: T): void => {
14
+ setCache<T>(key, data);
15
+ },
16
+ invalidateQuery: <T>(key: string, refetch?: () => Promise<T>): void => {
17
+ if (refetch) {
18
+ refetch()
19
+ .then((result) => setCache<T>(key, result))
20
+ .catch((err) => setCacheError<T>(key, err));
21
+ } else {
22
+ setCache<T>(key, undefined as unknown as T); // triggers update with undefined
23
+ }
24
+ },
25
+ clearQuery: (key: string): void => {
26
+ setCache<unknown>(key, undefined as unknown);
27
+ },
28
+ };
29
+ }