floppy-disk 2.0.0-alpha.4 → 2.0.0-alpha.6

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.
@@ -0,0 +1,35 @@
1
+ import { useEffect, useState } from 'preact/hooks';
2
+ import { initStore, } from '../vanilla';
3
+ export const createStore = (initializer, options = {}) => {
4
+ const { get, set, subscribe, getSubscribers } = initStore(initializer, options);
5
+ const { defaultDeps } = options;
6
+ /**
7
+ * IMPORTANT NOTE: selectDeps function must not be changed after initialization.
8
+ */
9
+ const useStore = (selectDeps = defaultDeps) => {
10
+ const [state, setState] = useState(get);
11
+ // eslint-disable-next-line react-hooks/exhaustive-deps
12
+ useEffect(() => subscribe(setState, selectDeps), []);
13
+ return state;
14
+ };
15
+ useStore.get = get;
16
+ useStore.set = set;
17
+ useStore.subscribe = subscribe;
18
+ useStore.getSubscribers = getSubscribers;
19
+ useStore.setDefaultValues = (value) => {
20
+ // eslint-disable-next-line react-hooks/rules-of-hooks
21
+ useState(() => {
22
+ const subscribers = getSubscribers();
23
+ if (subscribers.size > 0) {
24
+ console.warn('Put setDefaultValues on the root component or parent component, before any component subscribed!');
25
+ }
26
+ set(value);
27
+ });
28
+ };
29
+ const Watch = ({ selectDeps, render }) => {
30
+ const store = useStore(selectDeps);
31
+ return render(store);
32
+ };
33
+ useStore.Watch = Watch;
34
+ return useStore;
35
+ };
@@ -0,0 +1,45 @@
1
+ import { InitStoreOptions, InitStoreReturn, SelectDeps, SetStoreData, StoreData, Subscribers } from '../vanilla';
2
+ import { WatchProps } from './create-store';
3
+ type Maybe<T> = T | null | undefined;
4
+ export type StoreKey = Record<string, any> | undefined;
5
+ export type StoresInitializer<TKey extends StoreKey = StoreKey, T extends StoreData = StoreData> = (api: {
6
+ key: TKey;
7
+ get: () => T;
8
+ set: (value: SetStoreData<T>, silent?: boolean) => void;
9
+ }) => T;
10
+ export type UseStores<TKey extends StoreKey = StoreKey, T extends StoreData = StoreData> = {
11
+ /**
12
+ * @param key (Optional) Store key, an object that will be hashed into a string as a store identifier.
13
+ *
14
+ * @param selectDeps A function that return the dependency array (just like in `useEffect`), to trigger reactivity.
15
+ * Defaults to `undefined` (reactive to all state change) if you didn't set `defaultDeps` on `createStores`.
16
+ *
17
+ * IMPORTANT NOTE: `selectDeps` must not be changed after initialization.
18
+ */
19
+ (...args: [Maybe<TKey>, SelectDeps<T>?] | [SelectDeps<T>?]): T;
20
+ get: (key?: Maybe<TKey>) => T;
21
+ getAll: () => T[];
22
+ getAllWithSubscriber: () => T[];
23
+ set: (key: Maybe<TKey>, value: SetStoreData<T>, silent?: boolean) => void;
24
+ setAll: (value: SetStoreData<T>, silent?: boolean) => void;
25
+ subscribe: (key: Maybe<TKey>, fn: (state: T) => void, selectDeps?: SelectDeps<T>) => () => void;
26
+ getSubscribers: (key: Maybe<TKey>) => Subscribers<T>;
27
+ getStore: (key?: Maybe<TKey>) => InitStoreReturn<T>;
28
+ getStores: () => Map<string, InitStoreReturn<T>>;
29
+ /**
30
+ * Set default values inside a component.
31
+ *
32
+ * IMPORTANT NOTE: Put this on the root component or parent component, before any component subscribed!
33
+ */
34
+ setDefaultValues: (key: Maybe<TKey>, values: SetStoreData<T>) => void;
35
+ Watch: (props: WatchProps<T> & {
36
+ storeKey?: Maybe<TKey>;
37
+ }) => any;
38
+ };
39
+ export type CreateStoresOptions<TKey extends StoreKey = StoreKey, T extends StoreData = StoreData> = InitStoreOptions<T> & {
40
+ onBeforeChangeKey?: (nextKey: TKey, prevKey: TKey) => void;
41
+ defaultDeps?: SelectDeps<T>;
42
+ hashKeyFn?: (obj: TKey) => string;
43
+ };
44
+ export declare const createStores: <TKey extends StoreKey = StoreKey, T extends StoreData = StoreData>(initializer: StoresInitializer<TKey, T>, options?: CreateStoresOptions<TKey, T>) => UseStores<TKey, T>;
45
+ export {};
@@ -0,0 +1,96 @@
1
+ import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
2
+ import { hashStoreKey, noop } from '../utils';
3
+ import { initStore, } from '../vanilla';
4
+ export const createStores = (initializer, options = {}) => {
5
+ const { onBeforeChangeKey = noop, defaultDeps, hashKeyFn = hashStoreKey } = options;
6
+ const stores = new Map();
7
+ const getStore = (_key) => {
8
+ const key = _key || {};
9
+ const normalizedKey = hashKeyFn(key);
10
+ if (!stores.has(normalizedKey)) {
11
+ stores.set(normalizedKey, initStore((api) => initializer({ key, ...api }), options));
12
+ }
13
+ return stores.get(normalizedKey);
14
+ };
15
+ /**
16
+ * IMPORTANT NOTE: selectDeps function must not be changed after initialization.
17
+ */
18
+ const useStores = (...args) => {
19
+ const [_key, selectDeps = defaultDeps] = (typeof args[0] === 'function' ? [{}, args[0]] : args);
20
+ const key = _key || {};
21
+ const normalizedKey = hashKeyFn(key);
22
+ // eslint-disable-next-line react-hooks/exhaustive-deps
23
+ const { get, subscribe } = useMemo(() => getStore(key), [normalizedKey]);
24
+ const [state, setState] = useState(get);
25
+ const isFirstRender = useRef(true);
26
+ const prevKey = useRef(key);
27
+ useEffect(() => {
28
+ if (!isFirstRender.current) {
29
+ onBeforeChangeKey(key, prevKey.current);
30
+ setState(get);
31
+ }
32
+ isFirstRender.current = false;
33
+ prevKey.current = key;
34
+ const unsubs = subscribe(setState, selectDeps);
35
+ return unsubs;
36
+ // eslint-disable-next-line react-hooks/exhaustive-deps
37
+ }, [normalizedKey]);
38
+ return state;
39
+ };
40
+ useStores.get = (key) => {
41
+ const store = getStore(key);
42
+ return store.get();
43
+ };
44
+ useStores.getAll = () => {
45
+ const allStores = [];
46
+ stores.forEach((store) => {
47
+ allStores.push(store.get());
48
+ });
49
+ return allStores;
50
+ };
51
+ useStores.getAllWithSubscriber = () => {
52
+ const allStores = [];
53
+ stores.forEach((store) => {
54
+ const subscribers = store.getSubscribers();
55
+ if (subscribers.size > 0)
56
+ allStores.push(store.get());
57
+ });
58
+ return allStores;
59
+ };
60
+ useStores.set = (key, value, silent) => {
61
+ const store = getStore(key);
62
+ store.set(value, silent);
63
+ };
64
+ useStores.setAll = (value, silent) => {
65
+ stores.forEach((store) => {
66
+ store.set(value, silent);
67
+ });
68
+ };
69
+ useStores.subscribe = (key, fn, selectDeps) => {
70
+ const store = getStore(key);
71
+ return store.subscribe(fn, selectDeps);
72
+ };
73
+ useStores.getSubscribers = (key) => {
74
+ const store = getStore(key);
75
+ return store.getSubscribers();
76
+ };
77
+ useStores.getStore = (key) => getStore(key);
78
+ useStores.getStores = () => stores;
79
+ useStores.setDefaultValues = (key, value) => {
80
+ // eslint-disable-next-line react-hooks/rules-of-hooks
81
+ useState(() => {
82
+ const store = getStore(key);
83
+ const subscribers = store.getSubscribers();
84
+ if (subscribers.size > 0) {
85
+ console.warn('Put setDefaultValues on the root component or parent component, before any component subscribed!');
86
+ }
87
+ store.set(value);
88
+ });
89
+ };
90
+ const Watch = ({ storeKey, selectDeps, render }) => {
91
+ const store = useStores(storeKey, selectDeps);
92
+ return render(store);
93
+ };
94
+ useStores.Watch = Watch;
95
+ return useStores;
96
+ };
@@ -0,0 +1,5 @@
1
+ export * from './create-store';
2
+ export * from './create-stores';
3
+ export * from './create-query';
4
+ export * from './create-mutation';
5
+ export * from './with-context';
@@ -0,0 +1,5 @@
1
+ export * from './create-store';
2
+ export * from './create-stores';
3
+ export * from './create-query';
4
+ export * from './create-mutation';
5
+ export * from './with-context';
@@ -0,0 +1,6 @@
1
+ /// <reference types="react" />
2
+ import { ComponentChildren } from 'preact';
3
+ export declare const withContext: <T>(initFn: () => T) => readonly [({ children, onInitialize, }: {
4
+ children: ComponentChildren;
5
+ onInitialize?: ((value: T) => void) | undefined;
6
+ }) => import("react").JSX.Element, () => T | null];
@@ -0,0 +1,16 @@
1
+ import { createContext } from 'preact';
2
+ import { useContext, useState } from 'preact/hooks';
3
+ export const withContext = (initFn) => {
4
+ const Context = createContext(null);
5
+ const Provider = ({ children, onInitialize, }) => {
6
+ const [value] = useState(() => {
7
+ const store = initFn();
8
+ onInitialize && onInitialize(store);
9
+ return store;
10
+ });
11
+ // @ts-ignore
12
+ return React.createElement(Context.Provider, { value: value }, children);
13
+ };
14
+ const useCurrentContext = () => useContext(Context);
15
+ return [Provider, useCurrentContext];
16
+ };
@@ -25,6 +25,17 @@ export type QueryState<TKey extends StoreKey = StoreKey, TResponse = any, TData
25
25
  * Set query state (data, error, etc) to initial state.
26
26
  */
27
27
  reset: () => void;
28
+ /**
29
+ * Optimistic update.
30
+ *
31
+ * @returns function to revert the changes & function to invalidate the query
32
+ *
33
+ * IMPORTANT NOTE: This won't work well on infinite query.
34
+ */
35
+ optimisticUpdate: (response: TResponse | ((prevState: QueryState<TKey, TResponse, TData, TError>) => TResponse)) => {
36
+ revert: () => void;
37
+ invalidate: () => void;
38
+ };
28
39
  /**
29
40
  * Network fetching status.
30
41
  */
@@ -76,8 +76,10 @@ export const createQuery = (queryFn, options = {}) => {
76
76
  preventReplaceResponse.set(hashKeyFn(key), false);
77
77
  queryFn(key, stateBeforeCallQuery)
78
78
  .then((response) => {
79
- if (preventReplaceResponse.get(hashKeyFn(key)))
79
+ if (preventReplaceResponse.get(hashKeyFn(key))) {
80
+ set({ isWaiting: false });
80
81
  return;
82
+ }
81
83
  responseAllPages.push(response);
82
84
  const newPageParam = getNextPageParam(response, responseAllPages.length);
83
85
  newPageParams.push(newPageParam);
@@ -207,6 +209,7 @@ export const createQuery = (queryFn, options = {}) => {
207
209
  forceFetch,
208
210
  fetchNextPage,
209
211
  reset: () => set(INITIAL_QUERY_STATE),
212
+ optimisticUpdate: (response) => useQuery.optimisticUpdate({ key, response }),
210
213
  };
211
214
  }, (() => {
212
215
  const fetchWindowFocusHandler = () => {
@@ -0,0 +1,5 @@
1
+ export * from './create-store';
2
+ export * from './create-stores';
3
+ export * from './create-query';
4
+ export * from './create-mutation';
5
+ export * from './with-context';
@@ -0,0 +1,5 @@
1
+ export * from './create-store';
2
+ export * from './create-stores';
3
+ export * from './create-query';
4
+ export * from './create-mutation';
5
+ export * from './with-context';
package/lib/index.d.ts CHANGED
@@ -1,6 +1,2 @@
1
1
  export * from './vanilla';
2
- export * from './react/create-store';
3
- export * from './react/create-stores';
4
- export * from './react/create-query';
5
- export * from './react/create-mutation';
6
- export * from './react/with-context';
2
+ export * from './react';
package/lib/index.js CHANGED
@@ -2,8 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  tslib_1.__exportStar(require("./vanilla"), exports);
5
- tslib_1.__exportStar(require("./react/create-store"), exports);
6
- tslib_1.__exportStar(require("./react/create-stores"), exports);
7
- tslib_1.__exportStar(require("./react/create-query"), exports);
8
- tslib_1.__exportStar(require("./react/create-mutation"), exports);
9
- tslib_1.__exportStar(require("./react/with-context"), exports);
5
+ tslib_1.__exportStar(require("./react"), exports);
@@ -0,0 +1,28 @@
1
+ import { InitStoreOptions } from '../vanilla';
2
+ export type MutationState<TVar, TResponse = any, TError = unknown> = {
3
+ /**
4
+ * Network fetching status.
5
+ */
6
+ isWaiting: boolean;
7
+ isSuccess: boolean;
8
+ isError: boolean;
9
+ response: TResponse | null;
10
+ responseUpdatedAt: number | null;
11
+ error: TError | null;
12
+ errorUpdatedAt: number | null;
13
+ /**
14
+ * Mutate function is a promise that will always resolve.
15
+ */
16
+ mutate: (variables?: TVar) => Promise<{
17
+ response?: TResponse;
18
+ error?: TError;
19
+ variables?: TVar;
20
+ }>;
21
+ };
22
+ export type CreateMutationOptions<TVar, TResponse = any, TError = unknown> = InitStoreOptions<MutationState<TVar, TResponse, TError>> & {
23
+ onMutate?: (variables: TVar | undefined, stateBeforeMutate: MutationState<TVar, TResponse, TError>) => void;
24
+ onSuccess?: (response: TResponse, variables: TVar | undefined, stateBeforeMutate: MutationState<TVar, TResponse, TError>) => void;
25
+ onError?: (error: TError, variables: TVar | undefined, stateBeforeMutate: MutationState<TVar, TResponse, TError>) => void;
26
+ onSettled?: (variables: TVar | undefined, stateBeforeMutate: MutationState<TVar, TResponse, TError>) => void;
27
+ };
28
+ export declare const createMutation: <TVar, TResponse = any, TError = unknown>(mutationFn: (variables: TVar | undefined, state: MutationState<TVar, TResponse, TError>) => Promise<TResponse>, options?: CreateMutationOptions<TVar, TResponse, TError>) => import("./create-store").UseStore<MutationState<TVar, TResponse, TError>>;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMutation = void 0;
4
+ const utils_1 = require("../utils");
5
+ const create_store_1 = require("./create-store");
6
+ const createMutation = (mutationFn, options = {}) => {
7
+ const { onMutate = utils_1.noop, onSuccess = utils_1.noop, onError = utils_1.noop, onSettled = utils_1.noop, ...createStoreOptions } = options;
8
+ const useMutation = (0, create_store_1.createStore)(({ set, get }) => ({
9
+ isWaiting: false,
10
+ isSuccess: false,
11
+ isError: false,
12
+ response: null,
13
+ responseUpdatedAt: null,
14
+ error: null,
15
+ errorUpdatedAt: null,
16
+ mutate: (variables) => {
17
+ set({ isWaiting: true });
18
+ const stateBeforeMutate = get();
19
+ onMutate(variables, stateBeforeMutate);
20
+ return new Promise((resolve) => {
21
+ mutationFn(variables, stateBeforeMutate)
22
+ .then((response) => {
23
+ set({
24
+ isWaiting: false,
25
+ isSuccess: true,
26
+ isError: false,
27
+ response,
28
+ responseUpdatedAt: Date.now(),
29
+ error: null,
30
+ errorUpdatedAt: null,
31
+ });
32
+ onSuccess(response, variables, stateBeforeMutate);
33
+ resolve({ response, variables });
34
+ })
35
+ .catch((error) => {
36
+ set({
37
+ isWaiting: false,
38
+ isSuccess: false,
39
+ isError: true,
40
+ error,
41
+ errorUpdatedAt: Date.now(),
42
+ });
43
+ onError(error, variables, stateBeforeMutate);
44
+ resolve({ error, variables });
45
+ })
46
+ .finally(() => {
47
+ onSettled(variables, stateBeforeMutate);
48
+ });
49
+ });
50
+ },
51
+ }), createStoreOptions);
52
+ return useMutation;
53
+ };
54
+ exports.createMutation = createMutation;
@@ -0,0 +1,197 @@
1
+ import { CreateStoresOptions, StoreKey, UseStores } from './create-stores';
2
+ export type QueryStatus = 'loading' | 'success' | 'error';
3
+ export type QueryState<TKey extends StoreKey = StoreKey, TResponse = any, TData = TResponse, TError = unknown> = {
4
+ /**
5
+ * Query store key, an object that will be hashed into a string as a query store identifier.
6
+ */
7
+ key: TKey;
8
+ /**
9
+ * Will only be called if the data is stale or empty.
10
+ */
11
+ fetch: () => void;
12
+ /**
13
+ * Will be called even if the data is still fresh (not stale).
14
+ */
15
+ forceFetch: () => void;
16
+ /**
17
+ * Fetch next page if has next page.
18
+ *
19
+ * If the data is empty, it will just fetch the first page.
20
+ *
21
+ * You can ignore this if your query is not paginated.
22
+ */
23
+ fetchNextPage: () => void;
24
+ /**
25
+ * Set query state (data, error, etc) to initial state.
26
+ */
27
+ reset: () => void;
28
+ /**
29
+ * Optimistic update.
30
+ *
31
+ * @returns function to revert the changes & function to invalidate the query
32
+ *
33
+ * IMPORTANT NOTE: This won't work well on infinite query.
34
+ */
35
+ optimisticUpdate: (response: TResponse | ((prevState: QueryState<TKey, TResponse, TData, TError>) => TResponse)) => {
36
+ revert: () => void;
37
+ invalidate: () => void;
38
+ };
39
+ /**
40
+ * Network fetching status.
41
+ */
42
+ isWaiting: boolean;
43
+ /**
44
+ * Network fetching status for fetching next page.
45
+ */
46
+ isWaitingNextPage: boolean;
47
+ /**
48
+ * Status of the data.
49
+ *
50
+ * `"loading"` = no data.
51
+ *
52
+ * `"success"` = has data.
53
+ *
54
+ * `"error"` = has error.
55
+ *
56
+ * It has no relation with network fetching state.
57
+ * If you're looking for network fetching state, use `isWaiting` instead.
58
+ */
59
+ status: QueryStatus;
60
+ /**
61
+ * Data state, will be `true` if the query has no data.
62
+ *
63
+ * It has no relation with network fetching state.
64
+ * If you're looking for network fetching state, use `isWaiting` instead.
65
+ */
66
+ isLoading: boolean;
67
+ /**
68
+ * Data state, will be `true` if the query has a data.
69
+ */
70
+ isSuccess: boolean;
71
+ /**
72
+ * Error state, will be `true` after data fetching error.
73
+ */
74
+ isError: boolean;
75
+ isRefetching: boolean;
76
+ isRefetchError: boolean;
77
+ isPreviousData: boolean;
78
+ isOptimisticData: boolean;
79
+ data: TData | null;
80
+ response: TResponse | null;
81
+ responseUpdatedAt: number | null;
82
+ error: TError | null;
83
+ errorUpdatedAt: number | null;
84
+ retryCount: number;
85
+ isGoingToRetry: boolean;
86
+ pageParam: any;
87
+ pageParams: any[];
88
+ hasNextPage: boolean;
89
+ retryNextPageCount: number;
90
+ isGoingToRetryNextPage: boolean;
91
+ };
92
+ export type CreateQueryOptions<TKey extends StoreKey = StoreKey, TResponse = any, TData = TResponse, TError = unknown> = CreateStoresOptions<TKey, QueryState<TKey, TResponse, TData, TError>> & {
93
+ select?: (response: TResponse, state: Pick<QueryState<TKey, TResponse, TData, TError>, 'data' | 'key'>) => TData;
94
+ /**
95
+ * Stale time in miliseconds.
96
+ *
97
+ * Defaults to `3000` (3 seconds).
98
+ */
99
+ staleTime?: number;
100
+ /**
101
+ * Auto call the query when the component is mounted.
102
+ *
103
+ * Defaults to `true`.
104
+ *
105
+ * - If set to `true`, the query will be called on mount focus **if the data is stale**.
106
+ * - If set to `false`, the query won't be called on mount focus.
107
+ * - If set to `"always"`, the query will be called on mount focus.
108
+ */
109
+ fetchOnMount?: boolean | 'always' | ((key: TKey) => boolean | 'always');
110
+ /**
111
+ * Defaults to `true`.
112
+ *
113
+ * - If set to `true`, the query will be called on window focus **if the data is stale**.
114
+ * - If set to `false`, the query won't be called on window focus.
115
+ * - If set to `"always"`, the query will be called on window focus.
116
+ */
117
+ fetchOnWindowFocus?: boolean | 'always' | ((key: TKey) => boolean | 'always');
118
+ /**
119
+ * If set to `false` or return `false`, the query won't be called in any condition.
120
+ * Auto fetch on mount will be disabled.
121
+ * Manually trigger `fetch` method (returned from `createQuery`) won't work too.
122
+ *
123
+ * Defaults to `true`.
124
+ */
125
+ enabled?: boolean | ((key: TKey) => boolean);
126
+ /**
127
+ * Number of maximum error retries.
128
+ *
129
+ * Defaults to `1`.
130
+ */
131
+ retry?: number | ((error: TError, key: TKey) => number);
132
+ /**
133
+ * Error retry delay in miliseconds.
134
+ *
135
+ * Defaults to `3000` (3 seconds).
136
+ */
137
+ retryDelay?: number | ((error: TError, key: TKey) => number);
138
+ /**
139
+ * If set to `true`, previous `data` will be kept when fetching new data because the query key changed.
140
+ *
141
+ * This will only happened if there is no `data` in the next query.
142
+ */
143
+ keepPreviousData?: boolean;
144
+ /**
145
+ * Only set this if you have an infinite query.
146
+ *
147
+ * This function should return a variable that will be used when fetching next page (`pageParam`).
148
+ */
149
+ getNextPageParam?: (lastPage: TResponse, index: number) => any;
150
+ onSuccess?: (response: TResponse, stateBeforeCallQuery: QueryState<TKey, TResponse, TData, TError>) => void;
151
+ onError?: (error: TError, stateBeforeCallQuery: QueryState<TKey, TResponse, TData, TError>) => void;
152
+ onSettled?: (stateBeforeCallQuery: QueryState<TKey, TResponse, TData, TError>) => void;
153
+ };
154
+ export type UseQuery<TKey extends StoreKey = StoreKey, TResponse = any, TData = TResponse, TError = unknown> = UseStores<TKey, QueryState<TKey, TResponse, TData, TError>> & {
155
+ /**
156
+ * Set query's initial response.
157
+ *
158
+ * This is used for server-side rendered page or static page.
159
+ *
160
+ * IMPORTANT NOTE: Put this on the root component or parent component, before any component subscribed!
161
+ */
162
+ setInitialResponse: (options: {
163
+ key?: TKey;
164
+ response: TResponse;
165
+ }) => void;
166
+ /**
167
+ * Set query state (data, error, etc) to initial state.
168
+ */
169
+ reset: () => void;
170
+ /**
171
+ * Set query state (data, error, etc) to initial state.
172
+ */
173
+ resetSpecificKey: (key?: TKey | null) => void;
174
+ /**
175
+ * Invalidate query means marking a query as stale, and will refetch only if the query is active (has subscriber)
176
+ */
177
+ invalidate: () => void;
178
+ /**
179
+ * Invalidate query means marking a query as stale, and will refetch only if the query is active (has subscriber)
180
+ */
181
+ invalidateSpecificKey: (key?: TKey | null) => void;
182
+ /**
183
+ * Optimistic update.
184
+ *
185
+ * @returns function to revert the changes & function to invalidate the query
186
+ *
187
+ * IMPORTANT NOTE: This won't work well on infinite query.
188
+ */
189
+ optimisticUpdate: (options: {
190
+ key?: TKey | null;
191
+ response: TResponse | ((prevState: QueryState<TKey, TResponse, TData, TError>) => TResponse);
192
+ }) => {
193
+ revert: () => void;
194
+ invalidate: () => void;
195
+ };
196
+ };
197
+ export declare const createQuery: <TKey extends StoreKey = StoreKey, TResponse = any, TData = TResponse, TError = unknown>(queryFn: (key: TKey, state: QueryState<TKey, TResponse, TData, TError>) => Promise<TResponse>, options?: CreateQueryOptions<TKey, TResponse, TData, TError>) => UseQuery<TKey, TResponse, TData, TError>;