floppy-disk 3.0.0-experimental.1 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +256 -676
- package/esm/index.d.mts +1 -0
- package/esm/index.mjs +1 -0
- package/esm/react/create-mutation.d.mts +151 -0
- package/esm/react/create-query.d.mts +344 -0
- package/esm/react/create-store.d.mts +28 -0
- package/esm/react/create-stores.d.mts +39 -0
- package/esm/react/use-isomorphic-layout-effect.d.mts +6 -0
- package/esm/react/use-mutation.d.mts +82 -0
- package/esm/react/use-store.d.mts +28 -0
- package/esm/react.d.mts +7 -0
- package/esm/react.mjs +697 -0
- package/esm/vanilla/basic.d.mts +13 -0
- package/esm/vanilla/hash.d.mts +7 -0
- package/esm/vanilla/store.d.mts +89 -0
- package/esm/vanilla.d.mts +3 -0
- package/esm/vanilla.mjs +82 -0
- package/index.d.ts +1 -0
- package/index.js +12 -0
- package/package.json +47 -45
- package/react/create-mutation.d.ts +151 -0
- package/react/create-query.d.ts +344 -0
- package/react/create-store.d.ts +28 -0
- package/react/create-stores.d.ts +39 -0
- package/react/use-isomorphic-layout-effect.d.ts +6 -0
- package/react/use-mutation.d.ts +82 -0
- package/react/use-store.d.ts +28 -0
- package/react.d.ts +7 -0
- package/react.js +705 -0
- package/ts_version_4.5_and_above_is_required.d.ts +0 -0
- package/vanilla/basic.d.ts +13 -0
- package/vanilla/hash.d.ts +7 -0
- package/vanilla/store.d.ts +89 -0
- package/vanilla.d.ts +3 -0
- package/vanilla.js +89 -0
- package/esm/index.d.ts +0 -8
- package/esm/index.js +0 -8
- package/esm/react/create-bi-direction-query.d.ts +0 -166
- package/esm/react/create-bi-direction-query.js +0 -74
- package/esm/react/create-mutation.d.ts +0 -39
- package/esm/react/create-mutation.js +0 -56
- package/esm/react/create-query.d.ts +0 -319
- package/esm/react/create-query.js +0 -434
- package/esm/react/create-store.d.ts +0 -38
- package/esm/react/create-store.js +0 -38
- package/esm/react/create-stores.d.ts +0 -61
- package/esm/react/create-stores.js +0 -99
- package/esm/react/with-context.d.ts +0 -5
- package/esm/react/with-context.js +0 -14
- package/esm/utils.d.ts +0 -24
- package/esm/utils.js +0 -31
- package/esm/vanilla/fetcher.d.ts +0 -27
- package/esm/vanilla/fetcher.js +0 -95
- package/esm/vanilla/init-store.d.ts +0 -24
- package/esm/vanilla/init-store.js +0 -51
- package/lib/index.d.ts +0 -8
- package/lib/index.js +0 -11
- package/lib/react/create-bi-direction-query.d.ts +0 -166
- package/lib/react/create-bi-direction-query.js +0 -78
- package/lib/react/create-mutation.d.ts +0 -39
- package/lib/react/create-mutation.js +0 -60
- package/lib/react/create-query.d.ts +0 -319
- package/lib/react/create-query.js +0 -438
- package/lib/react/create-store.d.ts +0 -38
- package/lib/react/create-store.js +0 -42
- package/lib/react/create-stores.d.ts +0 -61
- package/lib/react/create-stores.js +0 -104
- package/lib/react/with-context.d.ts +0 -5
- package/lib/react/with-context.js +0 -18
- package/lib/utils.d.ts +0 -24
- package/lib/utils.js +0 -39
- package/lib/vanilla/fetcher.d.ts +0 -27
- package/lib/vanilla/fetcher.js +0 -99
- package/lib/vanilla/init-store.d.ts +0 -24
- package/lib/vanilla/init-store.js +0 -55
- package/utils/package.json +0 -6
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if this runs on browser.
|
|
3
|
+
*/
|
|
4
|
+
export declare const isClient: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Empty function.
|
|
7
|
+
*/
|
|
8
|
+
export declare const noop: () => void;
|
|
9
|
+
/**
|
|
10
|
+
* If the value is a function, it will invoke the function.\
|
|
11
|
+
* If the value is not a function, it will just return it.
|
|
12
|
+
*/
|
|
13
|
+
export declare const getValue: <T, P extends any[]>(valueOrComputeValueFn: T | ((...params: P) => T), ...params: P) => T;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const isPlainObject: (value: any) => boolean;
|
|
2
|
+
/**
|
|
3
|
+
* Get stable hash string from any value.
|
|
4
|
+
*
|
|
5
|
+
* Reference: https://github.com/TanStack/query/blob/v5.90.3/packages/query-core/src/utils.ts#L216
|
|
6
|
+
*/
|
|
7
|
+
export declare const getHash: (value?: any) => string;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a partial state update.
|
|
3
|
+
*
|
|
4
|
+
* Can be either:
|
|
5
|
+
* - A partial object to merge into the current state
|
|
6
|
+
* - A function that receives the current state and returns a partial update
|
|
7
|
+
*/
|
|
8
|
+
export type SetState<TState> = Partial<TState> | ((state: TState) => Partial<TState>);
|
|
9
|
+
/**
|
|
10
|
+
* A subscriber function that is called whenever the state updates.
|
|
11
|
+
*
|
|
12
|
+
* @param state - The latest state
|
|
13
|
+
* @param prevState - The previous state before the update
|
|
14
|
+
* @param changedKeys - The top-level keys that changed (shallow diff)
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* - Subscribers are only called when at least one field changes.
|
|
18
|
+
* - Change detection is performed per key using `Object.is`.
|
|
19
|
+
* - `changedKeys` only includes top-level keys; nested changes must be inferred by the consumer.
|
|
20
|
+
*/
|
|
21
|
+
export type Subscriber<TState> = (state: TState, prevState: TState, changedKeys: Array<keyof TState>) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Core store API for managing state.
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* - The store performs **shallow change detection per key** before notifying subscribers.
|
|
27
|
+
* - Subscribers are only notified when at least one field changes.
|
|
28
|
+
* - State is treated as **immutable**. Mutating nested values directly will not trigger updates.
|
|
29
|
+
* - Designed to be framework-agnostic (React bindings are built separately).
|
|
30
|
+
* - By default, `setState` is **disabled on the server** to prevent accidental shared state between requests.
|
|
31
|
+
*/
|
|
32
|
+
export type StoreApi<TState extends Record<string, any>> = {
|
|
33
|
+
setState: (value: SetState<TState>) => void;
|
|
34
|
+
getState: () => TState;
|
|
35
|
+
subscribe: (subscriber: Subscriber<TState>) => () => void;
|
|
36
|
+
getSubscribers: () => Set<Subscriber<TState>>;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Lifecycle hooks for the store.
|
|
40
|
+
*
|
|
41
|
+
* These hooks allow you to attach side effects based on subscription lifecycle.
|
|
42
|
+
*
|
|
43
|
+
* @remarks
|
|
44
|
+
* Useful for:
|
|
45
|
+
* - Lazy initialization (e.g. start fetching on first subscribe)
|
|
46
|
+
* - Cleanup (e.g. cancel timers, disconnect sockets)
|
|
47
|
+
* - Resource management (e.g. garbage collection)
|
|
48
|
+
*/
|
|
49
|
+
export type InitStoreOptions<TState extends Record<string, any>> = {
|
|
50
|
+
onFirstSubscribe?: (state: TState, store: StoreApi<TState>) => void;
|
|
51
|
+
onSubscribe?: (state: TState, store: StoreApi<TState>) => void;
|
|
52
|
+
onUnsubscribe?: (state: TState, store: StoreApi<TState>) => void;
|
|
53
|
+
onLastUnsubscribe?: (state: TState, store: StoreApi<TState>) => void;
|
|
54
|
+
/**
|
|
55
|
+
* By default, calling `setState` on the server is disallowed to prevent shared state across requests.
|
|
56
|
+
* Set this to `true` only if you explicitly intend to mutate state during server execution.
|
|
57
|
+
*/
|
|
58
|
+
allowSetStateServerSide?: boolean;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Creates a vanilla store with pub-sub capabilities.
|
|
62
|
+
*
|
|
63
|
+
* The store state must be an **object**.\
|
|
64
|
+
* Updates are applied as shallow merges, so non-object states are not supported.
|
|
65
|
+
*
|
|
66
|
+
* @param initialState - The initial state of the store
|
|
67
|
+
* @param options - Optional lifecycle hooks
|
|
68
|
+
*
|
|
69
|
+
* @returns A store API for managing state and subscriptions
|
|
70
|
+
*
|
|
71
|
+
* @remarks
|
|
72
|
+
* - State updates are **shallowly compared per key** before notifying subscribers.
|
|
73
|
+
* - Subscribers are only notified when at least one updated field changes (using `Object.is` comparison).
|
|
74
|
+
* - Subscribers receive the new state, previous state, and changed top-level keys.
|
|
75
|
+
* - State is expected to be treated as **immutable**.
|
|
76
|
+
* - Mutating nested values directly will not trigger updates.
|
|
77
|
+
* - Lifecycle hooks allow side-effect management tied to subscription count.
|
|
78
|
+
* - By default, `setState` is **not allowed on the server** to prevent accidental shared state between requests.
|
|
79
|
+
* - This helps avoid leaking data between users in server environments.
|
|
80
|
+
* - If you intentionally want to allow this behavior, set `allowSetStateServerSide: true`.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* const store = initStore({ count: 0 });
|
|
84
|
+
*
|
|
85
|
+
* store.subscribe((state) => console.log(state.count));
|
|
86
|
+
* store.setState({ count: 1 }); // triggers subscriber
|
|
87
|
+
* store.setState({ count: 1 }); // no-op (no change)
|
|
88
|
+
*/
|
|
89
|
+
export declare const initStore: <TState extends Record<string, any>>(initialState: TState, options?: InitStoreOptions<TState>) => StoreApi<TState>;
|
package/vanilla.d.ts
ADDED
package/vanilla.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const isClient = typeof window !== "undefined" && !("Deno" in window);
|
|
4
|
+
const noop = () => {
|
|
5
|
+
};
|
|
6
|
+
const getValue = (valueOrComputeValueFn, ...params) => {
|
|
7
|
+
if (typeof valueOrComputeValueFn === "function") {
|
|
8
|
+
return valueOrComputeValueFn(...params);
|
|
9
|
+
}
|
|
10
|
+
return valueOrComputeValueFn;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const hasObjectPrototype = (value) => {
|
|
14
|
+
return Object.prototype.toString.call(value) === "[object Object]";
|
|
15
|
+
};
|
|
16
|
+
const isPlainObject = (value) => {
|
|
17
|
+
if (!hasObjectPrototype(value)) return false;
|
|
18
|
+
const ctor = value.constructor;
|
|
19
|
+
if (typeof ctor === "undefined") return true;
|
|
20
|
+
const prot = ctor.prototype;
|
|
21
|
+
if (!hasObjectPrototype(prot)) return false;
|
|
22
|
+
if (!prot.hasOwnProperty("isPrototypeOf")) return false;
|
|
23
|
+
if (Object.getPrototypeOf(value) !== Object.prototype) return false;
|
|
24
|
+
return true;
|
|
25
|
+
};
|
|
26
|
+
const getHash = (value) => JSON.stringify(
|
|
27
|
+
value,
|
|
28
|
+
(_, val) => isPlainObject(val) ? Object.keys(val).sort().reduce((result, key) => {
|
|
29
|
+
result[key] = val[key];
|
|
30
|
+
return result;
|
|
31
|
+
}, {}) : val
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const initStore = (initialState, options = {}) => {
|
|
35
|
+
const {
|
|
36
|
+
onFirstSubscribe = noop,
|
|
37
|
+
onSubscribe = noop,
|
|
38
|
+
onUnsubscribe = noop,
|
|
39
|
+
onLastUnsubscribe = noop,
|
|
40
|
+
allowSetStateServerSide = false
|
|
41
|
+
} = options;
|
|
42
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
43
|
+
const getSubscribers = () => subscribers;
|
|
44
|
+
const subscribe = (subscriber) => {
|
|
45
|
+
subscribers.add(subscriber);
|
|
46
|
+
if (subscribers.size === 1) onFirstSubscribe(state, storeApi);
|
|
47
|
+
onSubscribe(state, storeApi);
|
|
48
|
+
return () => {
|
|
49
|
+
subscribers.delete(subscriber);
|
|
50
|
+
onUnsubscribe(state, storeApi);
|
|
51
|
+
if (subscribers.size === 0) onLastUnsubscribe(state, storeApi);
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
let state = initialState;
|
|
55
|
+
const getState = () => state;
|
|
56
|
+
const setState = (value) => {
|
|
57
|
+
if (!isClient && !allowSetStateServerSide) {
|
|
58
|
+
console.error(
|
|
59
|
+
"setState on the server is not allowed by default. Set `allowSetStateServerSide: true` to allow it."
|
|
60
|
+
);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const prevState = state;
|
|
64
|
+
const newValue = getValue(value, state);
|
|
65
|
+
const changedKeys = [];
|
|
66
|
+
for (const key in newValue) {
|
|
67
|
+
if (!Object.is(prevState[key], newValue[key])) {
|
|
68
|
+
changedKeys.push(key);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (changedKeys.length === 0) return;
|
|
72
|
+
state = { ...prevState, ...newValue };
|
|
73
|
+
[...subscribers].forEach((subscriber) => subscriber(state, prevState, changedKeys));
|
|
74
|
+
};
|
|
75
|
+
const storeApi = {
|
|
76
|
+
getState,
|
|
77
|
+
setState,
|
|
78
|
+
subscribe,
|
|
79
|
+
getSubscribers
|
|
80
|
+
};
|
|
81
|
+
return storeApi;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
exports.getHash = getHash;
|
|
85
|
+
exports.getValue = getValue;
|
|
86
|
+
exports.initStore = initStore;
|
|
87
|
+
exports.isClient = isClient;
|
|
88
|
+
exports.isPlainObject = isPlainObject;
|
|
89
|
+
exports.noop = noop;
|
package/esm/index.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export * from './vanilla/init-store';
|
|
2
|
-
export * from './vanilla/fetcher';
|
|
3
|
-
export * from './react/create-store';
|
|
4
|
-
export * from './react/create-stores';
|
|
5
|
-
export * from './react/create-query';
|
|
6
|
-
export * from './react/create-bi-direction-query';
|
|
7
|
-
export * from './react/create-mutation';
|
|
8
|
-
export * from './react/with-context';
|
package/esm/index.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export * from './vanilla/init-store';
|
|
2
|
-
export * from './vanilla/fetcher';
|
|
3
|
-
export * from './react/create-store';
|
|
4
|
-
export * from './react/create-stores';
|
|
5
|
-
export * from './react/create-query';
|
|
6
|
-
export * from './react/create-bi-direction-query';
|
|
7
|
-
export * from './react/create-mutation';
|
|
8
|
-
export * from './react/with-context';
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import { Maybe } from '../utils';
|
|
2
|
-
import { CreateQueryOptions, QueryState } from './create-query';
|
|
3
|
-
import { StoreKey } from './create-stores';
|
|
4
|
-
export declare const createBiDirectionQuery: <TKey extends StoreKey = StoreKey, TResponse = any, TData extends any[] = any[], TError = unknown, TPageParam = any>(queryFn: (key: TKey, state: QueryState<TKey, TResponse, TData, TError, TPageParam>, direction: 'prev' | 'next') => Promise<TResponse>, options: Omit<CreateQueryOptions<TKey, TResponse, TData, TError, TPageParam>, "select" | "getNextPageParam"> & {
|
|
5
|
-
getPrevPageParam: (lastPage: TResponse, index: number, stateBeforeCallQuery: QueryState<TKey, TResponse, TData, TError, TPageParam>) => Maybe<TPageParam>;
|
|
6
|
-
getNextPageParam: (lastPage: TResponse, index: number, stateBeforeCallQuery: QueryState<TKey, TResponse, TData, TError, TPageParam>) => Maybe<TPageParam>;
|
|
7
|
-
select: (response: TResponse, state: Pick<QueryState<TKey, TResponse, TData, TError, TPageParam>, "data" | "key">, direction: 'prev' | 'next') => TData;
|
|
8
|
-
}) => {
|
|
9
|
-
(...args: [Maybe<TKey>, import("..").SelectDeps<QueryState<TKey, TResponse, TData, TError, TPageParam>>?] | [import("..").SelectDeps<QueryState<TKey, TResponse, TData, TError, TPageParam>>?]): {
|
|
10
|
-
data: (never[] | TData)[number][];
|
|
11
|
-
fetchPrevPage: () => Promise<QueryState<TKey, TResponse, TData, TError, TPageParam>>;
|
|
12
|
-
hasPrevPage: boolean;
|
|
13
|
-
isWaitingPrevPage: boolean;
|
|
14
|
-
key: TKey;
|
|
15
|
-
keyHash: string;
|
|
16
|
-
fetch: () => void;
|
|
17
|
-
forceFetch: () => Promise<QueryState<TKey, TResponse, TData, TError, TPageParam>>;
|
|
18
|
-
fetchNextPage: () => Promise<QueryState<TKey, TResponse, TData, TError, TPageParam>>;
|
|
19
|
-
reset: () => void;
|
|
20
|
-
optimisticUpdate: (response: TResponse | ((prevState: QueryState<TKey, TResponse, TData, TError, TPageParam>) => TResponse)) => {
|
|
21
|
-
revert: () => void;
|
|
22
|
-
invalidate: () => void;
|
|
23
|
-
};
|
|
24
|
-
isWaiting: boolean;
|
|
25
|
-
isWaitingNextPage: boolean;
|
|
26
|
-
isRefetching: boolean;
|
|
27
|
-
isRefetchError: boolean;
|
|
28
|
-
isPreviousData: boolean;
|
|
29
|
-
isOptimisticData: boolean;
|
|
30
|
-
error: TError | undefined;
|
|
31
|
-
errorUpdatedAt: number | undefined;
|
|
32
|
-
retryCount: number;
|
|
33
|
-
isGoingToRetry: boolean;
|
|
34
|
-
pageParam: Maybe<TPageParam>;
|
|
35
|
-
pageParams: Maybe<TPageParam>[];
|
|
36
|
-
hasNextPage: boolean;
|
|
37
|
-
retryNextPageCount: number;
|
|
38
|
-
isGoingToRetryNextPage: boolean;
|
|
39
|
-
status: "loading";
|
|
40
|
-
isLoading: true;
|
|
41
|
-
isSuccess: false;
|
|
42
|
-
isError: false;
|
|
43
|
-
response: undefined;
|
|
44
|
-
responseUpdatedAt: undefined;
|
|
45
|
-
} | {
|
|
46
|
-
data: (never[] | TData)[number][];
|
|
47
|
-
fetchPrevPage: () => Promise<QueryState<TKey, TResponse, TData, TError, TPageParam>>;
|
|
48
|
-
hasPrevPage: boolean;
|
|
49
|
-
isWaitingPrevPage: boolean;
|
|
50
|
-
key: TKey;
|
|
51
|
-
keyHash: string;
|
|
52
|
-
fetch: () => void;
|
|
53
|
-
forceFetch: () => Promise<QueryState<TKey, TResponse, TData, TError, TPageParam>>;
|
|
54
|
-
fetchNextPage: () => Promise<QueryState<TKey, TResponse, TData, TError, TPageParam>>;
|
|
55
|
-
reset: () => void;
|
|
56
|
-
optimisticUpdate: (response: TResponse | ((prevState: QueryState<TKey, TResponse, TData, TError, TPageParam>) => TResponse)) => {
|
|
57
|
-
revert: () => void;
|
|
58
|
-
invalidate: () => void;
|
|
59
|
-
};
|
|
60
|
-
isWaiting: boolean;
|
|
61
|
-
isWaitingNextPage: boolean;
|
|
62
|
-
isRefetching: boolean;
|
|
63
|
-
isRefetchError: boolean;
|
|
64
|
-
isPreviousData: boolean;
|
|
65
|
-
isOptimisticData: boolean;
|
|
66
|
-
error: TError | undefined;
|
|
67
|
-
errorUpdatedAt: number | undefined;
|
|
68
|
-
retryCount: number;
|
|
69
|
-
isGoingToRetry: boolean;
|
|
70
|
-
pageParam: Maybe<TPageParam>;
|
|
71
|
-
pageParams: Maybe<TPageParam>[];
|
|
72
|
-
hasNextPage: boolean;
|
|
73
|
-
retryNextPageCount: number;
|
|
74
|
-
isGoingToRetryNextPage: boolean;
|
|
75
|
-
status: "error";
|
|
76
|
-
isLoading: false;
|
|
77
|
-
isSuccess: false;
|
|
78
|
-
isError: true;
|
|
79
|
-
response: undefined;
|
|
80
|
-
responseUpdatedAt: undefined;
|
|
81
|
-
} | {
|
|
82
|
-
data: (never[] | TData)[number][];
|
|
83
|
-
fetchPrevPage: () => Promise<QueryState<TKey, TResponse, TData, TError, TPageParam>>;
|
|
84
|
-
hasPrevPage: boolean;
|
|
85
|
-
isWaitingPrevPage: boolean;
|
|
86
|
-
key: TKey;
|
|
87
|
-
keyHash: string;
|
|
88
|
-
fetch: () => void;
|
|
89
|
-
forceFetch: () => Promise<QueryState<TKey, TResponse, TData, TError, TPageParam>>;
|
|
90
|
-
fetchNextPage: () => Promise<QueryState<TKey, TResponse, TData, TError, TPageParam>>;
|
|
91
|
-
reset: () => void;
|
|
92
|
-
optimisticUpdate: (response: TResponse | ((prevState: QueryState<TKey, TResponse, TData, TError, TPageParam>) => TResponse)) => {
|
|
93
|
-
revert: () => void;
|
|
94
|
-
invalidate: () => void;
|
|
95
|
-
};
|
|
96
|
-
isWaiting: boolean;
|
|
97
|
-
isWaitingNextPage: boolean;
|
|
98
|
-
isRefetching: boolean;
|
|
99
|
-
isRefetchError: boolean;
|
|
100
|
-
isPreviousData: boolean;
|
|
101
|
-
isOptimisticData: boolean;
|
|
102
|
-
error: TError | undefined;
|
|
103
|
-
errorUpdatedAt: number | undefined;
|
|
104
|
-
retryCount: number;
|
|
105
|
-
isGoingToRetry: boolean;
|
|
106
|
-
pageParam: Maybe<TPageParam>;
|
|
107
|
-
pageParams: Maybe<TPageParam>[];
|
|
108
|
-
hasNextPage: boolean;
|
|
109
|
-
retryNextPageCount: number;
|
|
110
|
-
isGoingToRetryNextPage: boolean;
|
|
111
|
-
status: "success";
|
|
112
|
-
isLoading: false;
|
|
113
|
-
isSuccess: true;
|
|
114
|
-
isError: false;
|
|
115
|
-
response: TResponse;
|
|
116
|
-
responseUpdatedAt: number | undefined;
|
|
117
|
-
};
|
|
118
|
-
get(): {
|
|
119
|
-
prev: QueryState<TKey, TResponse, TData, TError, TPageParam>;
|
|
120
|
-
next: QueryState<TKey, TResponse, TData, TError, TPageParam>;
|
|
121
|
-
};
|
|
122
|
-
setInitialResponse: (options: {
|
|
123
|
-
key?: Maybe<TKey>;
|
|
124
|
-
response: TResponse;
|
|
125
|
-
skipRevalidation?: boolean | undefined;
|
|
126
|
-
}) => void;
|
|
127
|
-
reset(): void;
|
|
128
|
-
resetSpecificKey(key: Maybe<TKey>): void;
|
|
129
|
-
invalidate: () => void;
|
|
130
|
-
invalidateSpecificKey: (key?: Maybe<TKey>) => void;
|
|
131
|
-
suspend: (key?: Maybe<TKey>) => {
|
|
132
|
-
key: TKey;
|
|
133
|
-
keyHash: string;
|
|
134
|
-
fetch: () => void;
|
|
135
|
-
forceFetch: () => Promise<QueryState<TKey, TResponse, TData, TError, TPageParam>>;
|
|
136
|
-
fetchNextPage: () => Promise<QueryState<TKey, TResponse, TData, TError, TPageParam>>;
|
|
137
|
-
reset: () => void;
|
|
138
|
-
optimisticUpdate: (response: TResponse | ((prevState: QueryState<TKey, TResponse, TData, TError, TPageParam>) => TResponse)) => {
|
|
139
|
-
revert: () => void;
|
|
140
|
-
invalidate: () => void;
|
|
141
|
-
};
|
|
142
|
-
isWaiting: boolean;
|
|
143
|
-
isWaitingNextPage: boolean;
|
|
144
|
-
isRefetching: boolean;
|
|
145
|
-
isRefetchError: boolean;
|
|
146
|
-
isPreviousData: boolean;
|
|
147
|
-
isOptimisticData: boolean;
|
|
148
|
-
error: TError | undefined;
|
|
149
|
-
errorUpdatedAt: number | undefined;
|
|
150
|
-
retryCount: number;
|
|
151
|
-
isGoingToRetry: boolean;
|
|
152
|
-
pageParam: Maybe<TPageParam>;
|
|
153
|
-
pageParams: Maybe<TPageParam>[];
|
|
154
|
-
hasNextPage: boolean;
|
|
155
|
-
retryNextPageCount: number;
|
|
156
|
-
isGoingToRetryNextPage: boolean;
|
|
157
|
-
} & {
|
|
158
|
-
status: "success";
|
|
159
|
-
isLoading: false;
|
|
160
|
-
isSuccess: true;
|
|
161
|
-
isError: false;
|
|
162
|
-
data: TData;
|
|
163
|
-
response: TResponse;
|
|
164
|
-
responseUpdatedAt: number | undefined;
|
|
165
|
-
};
|
|
166
|
-
};
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { hasValue } from '../utils';
|
|
2
|
-
import { createQuery } from './create-query';
|
|
3
|
-
export const createBiDirectionQuery = (queryFn, options) => {
|
|
4
|
-
const { getPrevPageParam, getNextPageParam, select, ...restOptions } = options;
|
|
5
|
-
const usePrevPagesQuery = createQuery((key, state) => queryFn(key, state, 'prev'), {
|
|
6
|
-
defaultDeps: (state) => [
|
|
7
|
-
state.isWaiting,
|
|
8
|
-
state.data,
|
|
9
|
-
state.error,
|
|
10
|
-
state.isWaitingNextPage,
|
|
11
|
-
state.hasNextPage,
|
|
12
|
-
],
|
|
13
|
-
fetchOnMount: false,
|
|
14
|
-
getNextPageParam: getPrevPageParam,
|
|
15
|
-
select: (response, state) => select(response, state, 'prev'),
|
|
16
|
-
...restOptions,
|
|
17
|
-
});
|
|
18
|
-
const useNextPagesQuery = createQuery(async (key, state) => {
|
|
19
|
-
const isInitialPage = state.pageParam === undefined;
|
|
20
|
-
const pQuery = usePrevPagesQuery.get(key);
|
|
21
|
-
try {
|
|
22
|
-
const response = await queryFn(key, state, 'next');
|
|
23
|
-
if (isInitialPage) {
|
|
24
|
-
const prevPageParam = getPrevPageParam(response, 1, pQuery);
|
|
25
|
-
usePrevPagesQuery.set(key, (prev) => ({
|
|
26
|
-
pageParams: [prevPageParam, ...prev.pageParams.slice(1)],
|
|
27
|
-
hasNextPage: prev.isLoading ? hasValue(prevPageParam) : prev.hasNextPage,
|
|
28
|
-
}));
|
|
29
|
-
if (!pQuery.isLoading)
|
|
30
|
-
pQuery.forceFetch();
|
|
31
|
-
}
|
|
32
|
-
return response;
|
|
33
|
-
}
|
|
34
|
-
catch (error) {
|
|
35
|
-
if (isInitialPage && !pQuery.isLoading)
|
|
36
|
-
pQuery.reset();
|
|
37
|
-
throw error;
|
|
38
|
-
}
|
|
39
|
-
}, {
|
|
40
|
-
getNextPageParam: getNextPageParam,
|
|
41
|
-
select: (response, state) => select(response, state, 'next'),
|
|
42
|
-
...restOptions,
|
|
43
|
-
});
|
|
44
|
-
const useBiDirectionQuery = (...args) => {
|
|
45
|
-
const pQuery = usePrevPagesQuery(...args);
|
|
46
|
-
const nQuery = useNextPagesQuery(...args);
|
|
47
|
-
return {
|
|
48
|
-
...nQuery,
|
|
49
|
-
data: [...(pQuery.data || []), ...(nQuery.data || [])],
|
|
50
|
-
fetchPrevPage: pQuery.fetchNextPage,
|
|
51
|
-
hasPrevPage: pQuery.hasNextPage,
|
|
52
|
-
isWaitingPrevPage: pQuery.isWaitingNextPage || (pQuery.isLoading && pQuery.isWaiting),
|
|
53
|
-
};
|
|
54
|
-
};
|
|
55
|
-
useBiDirectionQuery.get = () => {
|
|
56
|
-
return {
|
|
57
|
-
prev: usePrevPagesQuery.get(),
|
|
58
|
-
next: useNextPagesQuery.get(),
|
|
59
|
-
};
|
|
60
|
-
};
|
|
61
|
-
useBiDirectionQuery.setInitialResponse = useNextPagesQuery.setInitialResponse;
|
|
62
|
-
useBiDirectionQuery.reset = () => {
|
|
63
|
-
usePrevPagesQuery.reset();
|
|
64
|
-
useNextPagesQuery.reset();
|
|
65
|
-
};
|
|
66
|
-
useBiDirectionQuery.resetSpecificKey = (key) => {
|
|
67
|
-
usePrevPagesQuery.resetSpecificKey(key);
|
|
68
|
-
useNextPagesQuery.resetSpecificKey(key);
|
|
69
|
-
};
|
|
70
|
-
useBiDirectionQuery.invalidate = useNextPagesQuery.invalidate;
|
|
71
|
-
useBiDirectionQuery.invalidateSpecificKey = useNextPagesQuery.invalidateSpecificKey;
|
|
72
|
-
useBiDirectionQuery.suspend = useNextPagesQuery.suspend;
|
|
73
|
-
return useBiDirectionQuery;
|
|
74
|
-
};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { InitStoreOptions } from '../vanilla/init-store';
|
|
2
|
-
import { UseStore } from './create-store';
|
|
3
|
-
export type MutationState<TVar, TResponse = any, TError = unknown> = {
|
|
4
|
-
/**
|
|
5
|
-
* Network fetching status.
|
|
6
|
-
*/
|
|
7
|
-
isWaiting: boolean;
|
|
8
|
-
isSuccess: boolean;
|
|
9
|
-
isError: boolean;
|
|
10
|
-
response: TResponse | undefined;
|
|
11
|
-
responseUpdatedAt: number | undefined;
|
|
12
|
-
error: TError | undefined;
|
|
13
|
-
errorUpdatedAt: number | undefined;
|
|
14
|
-
/**
|
|
15
|
-
* Mutate function.
|
|
16
|
-
*
|
|
17
|
-
* @returns Promise that will always get resolved.
|
|
18
|
-
*/
|
|
19
|
-
mutate: TVar extends undefined ? () => Promise<{
|
|
20
|
-
response?: TResponse;
|
|
21
|
-
error?: TError;
|
|
22
|
-
variables?: TVar;
|
|
23
|
-
}> : (variables: TVar) => Promise<{
|
|
24
|
-
response?: TResponse;
|
|
25
|
-
error?: TError;
|
|
26
|
-
variables?: TVar;
|
|
27
|
-
}>;
|
|
28
|
-
};
|
|
29
|
-
export type UseMutation<TVar, TResponse = any, TError = unknown> = UseStore<MutationState<TVar, TResponse, TError>>;
|
|
30
|
-
export type CreateMutationOptions<TVar, TResponse = any, TError = unknown> = InitStoreOptions<MutationState<TVar, TResponse, TError>> & {
|
|
31
|
-
onMutate?: (variables: TVar, stateBeforeMutate: MutationState<TVar, TResponse, TError>) => void;
|
|
32
|
-
onSuccess?: (response: TResponse, variables: TVar, stateBeforeMutate: MutationState<TVar, TResponse, TError>) => void;
|
|
33
|
-
onError?: (error: TError, variables: TVar, stateBeforeMutate: MutationState<TVar, TResponse, TError>) => void;
|
|
34
|
-
onSettled?: (variables: TVar, stateBeforeMutate: MutationState<TVar, TResponse, TError>) => void;
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* @see https://floppy-disk.vercel.app/docs/api#createmutation
|
|
38
|
-
*/
|
|
39
|
-
export declare const createMutation: <TVar, TResponse = any, TError = unknown>(mutationFn: (variables: TVar, state: MutationState<TVar, TResponse, TError>) => Promise<TResponse>, options?: CreateMutationOptions<TVar, TResponse, TError>) => UseMutation<TVar, TResponse, TError>;
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { noop } from '../utils';
|
|
2
|
-
import { createStore } from './create-store';
|
|
3
|
-
/**
|
|
4
|
-
* @see https://floppy-disk.vercel.app/docs/api#createmutation
|
|
5
|
-
*/
|
|
6
|
-
export const createMutation = (mutationFn, options = {}) => {
|
|
7
|
-
const { onMutate = noop, onSuccess = noop, onError, onSettled = noop, ...createStoreOptions } = options;
|
|
8
|
-
const useMutation = createStore(({ set, get }) => ({
|
|
9
|
-
isWaiting: false,
|
|
10
|
-
isSuccess: false,
|
|
11
|
-
isError: false,
|
|
12
|
-
response: undefined,
|
|
13
|
-
responseUpdatedAt: undefined,
|
|
14
|
-
error: undefined,
|
|
15
|
-
errorUpdatedAt: undefined,
|
|
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: undefined,
|
|
30
|
-
errorUpdatedAt: undefined,
|
|
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
|
-
if (onError)
|
|
44
|
-
onError(error, variables, stateBeforeMutate);
|
|
45
|
-
else
|
|
46
|
-
console.error(error, variables, get());
|
|
47
|
-
resolve({ error, variables });
|
|
48
|
-
})
|
|
49
|
-
.finally(() => {
|
|
50
|
-
onSettled(variables, stateBeforeMutate);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
}),
|
|
54
|
-
}), createStoreOptions);
|
|
55
|
-
return useMutation;
|
|
56
|
-
};
|