@ahoo-wang/wow-react 9.2.0-rc.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.
- package/LICENSE +201 -0
- package/README.md +253 -0
- package/README.zh-CN.md +231 -0
- package/dist/hooks/useCountQuery.d.ts +61 -0
- package/dist/hooks/useFetcherCountQuery.d.ts +65 -0
- package/dist/hooks/useFetcherListQuery.d.ts +78 -0
- package/dist/hooks/useFetcherListStreamQuery.d.ts +63 -0
- package/dist/hooks/useFetcherPagedQuery.d.ts +73 -0
- package/dist/hooks/useFetcherSingleQuery.d.ts +69 -0
- package/dist/hooks/useListQuery.d.ts +68 -0
- package/dist/hooks/useListStreamQuery.d.ts +89 -0
- package/dist/hooks/usePagedQuery.d.ts +68 -0
- package/dist/hooks/useSingleQuery.d.ts +64 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.es.js +298 -0
- package/dist/index.es.js.map +1 -0
- package/dist/internal/endpoint.d.ts +41 -0
- package/dist/internal/queryTransitions.d.ts +40 -0
- package/dist/internal/readStreamRows.d.ts +25 -0
- package/dist/internal/useEndpointRunner.d.ts +8 -0
- package/dist/internal/useListStream.d.ts +11 -0
- package/dist/internal/useQueryRunner.d.ts +21 -0
- package/dist/types.d.ts +114 -0
- package/package.json +86 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { FilterListQuery } from '@ahoo-wang/wow-client';
|
|
2
|
+
import { ListQuery, ListQueryRequest } from '@ahoo-wang/wow-client/legacy';
|
|
3
|
+
import { QueryHookOptions, QueryHookReturn } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Options of {@link useListQuery}: a list query and an `execute` that resolves
|
|
6
|
+
* to its rows.
|
|
7
|
+
*
|
|
8
|
+
* @template R - One row of the list
|
|
9
|
+
* @template FIELDS - The field names the query may use
|
|
10
|
+
* @template E - The error type, `Error` by default
|
|
11
|
+
* @template Q - The query type: `FilterListQuery` by default
|
|
12
|
+
*/
|
|
13
|
+
export interface UseListQueryOptions<R, FIELDS extends string = string, E = Error, Q extends ListQueryRequest<FIELDS> = FilterListQuery<FIELDS>> extends QueryHookOptions<Q, R[], E> {
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* What {@link useListQuery} returns: the rows as `result`.
|
|
17
|
+
*
|
|
18
|
+
* @template R - One row of the list
|
|
19
|
+
* @template FIELDS - The field names the query may use
|
|
20
|
+
* @template E - The error type, `Error` by default
|
|
21
|
+
* @template Q - The query type: `FilterListQuery` by default
|
|
22
|
+
*/
|
|
23
|
+
export interface UseListQueryReturn<R, FIELDS extends string = string, E = Error, Q extends ListQueryRequest<FIELDS> = FilterListQuery<FIELDS>> extends QueryHookReturn<Q, R[], E> {
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Runs a list query through your own `execute` function and keeps the rows
|
|
27
|
+
* as state: typically a query client's `list` or `listState`.
|
|
28
|
+
*
|
|
29
|
+
* `execute` receives the query, the `attributes` option and an
|
|
30
|
+
* `AbortController`; hand the controller on so that a newer query, `abort()`
|
|
31
|
+
* or an unmount cancels the request. The query runs on mount and whenever
|
|
32
|
+
* `query` or `setQuery()` changes it; set `autoExecute: false` to run it only
|
|
33
|
+
* through `execute()`.
|
|
34
|
+
*
|
|
35
|
+
* Returns `result` (the rows, or `undefined` before the first success),
|
|
36
|
+
* `loading`, `error`, `status`, `execute`, `abort`, `reset`, `getQuery` and
|
|
37
|
+
* `setQuery`.
|
|
38
|
+
*
|
|
39
|
+
* @template R - One row of the list
|
|
40
|
+
* @template FIELDS - The field names the query may use. With a client whose
|
|
41
|
+
* fields are narrower than `string`, as a generated client's are, pass
|
|
42
|
+
* them here: TypeScript does not infer them from `execute` once `R` is given
|
|
43
|
+
* @template E - The error type, `Error` by default
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```tsx
|
|
47
|
+
* import { desc, filter, listQuery, type SnapshotQueryClient } from '@ahoo-wang/wow-client';
|
|
48
|
+
* import { useListQuery } from '@ahoo-wang/wow-react';
|
|
49
|
+
*
|
|
50
|
+
* function LatestOrders({ client }: { client: SnapshotQueryClient<OrderState, OrderFields> }) {
|
|
51
|
+
* const { result, loading, error } = useListQuery<OrderState, OrderFields>({
|
|
52
|
+
* initialQuery: listQuery({
|
|
53
|
+
* filter: filter.eq('state.status', 'PAID'),
|
|
54
|
+
* sort: [desc('createTime')],
|
|
55
|
+
* limit: 20,
|
|
56
|
+
* }),
|
|
57
|
+
* execute: (query, attributes, abortController) =>
|
|
58
|
+
* client.listState(query, attributes, abortController),
|
|
59
|
+
* });
|
|
60
|
+
* if (error) return <p role="alert">{error.message}</p>;
|
|
61
|
+
* if (loading || !result) return <p>Loading…</p>;
|
|
62
|
+
* return <ul>{result.map(order => <li key={order.id}>{order.id}</li>)}</ul>;
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare function useListQuery<R, FIELDS extends string = string, E = Error>(options: UseListQueryOptions<R, FIELDS, E, FilterListQuery<FIELDS>>): UseListQueryReturn<R, FIELDS, E, FilterListQuery<FIELDS>>;
|
|
67
|
+
export declare function useListQuery<R, FIELDS extends string = string, E = Error>(options: UseListQueryOptions<R, FIELDS, E, ListQuery<FIELDS>>): UseListQueryReturn<R, FIELDS, E, ListQuery<FIELDS>>;
|
|
68
|
+
export declare function useListQuery<R, FIELDS extends string = string, E = Error, Q extends ListQueryRequest<FIELDS> = FilterListQuery<FIELDS>>(options: UseListQueryOptions<R, FIELDS, E, Q>): UseListQueryReturn<R, FIELDS, E, Q>;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { FilterListQuery } from '@ahoo-wang/wow-client';
|
|
2
|
+
import { ListQuery, ListQueryRequest } from '@ahoo-wang/wow-client/legacy';
|
|
3
|
+
import { ListStreamExecutor, QueryHookOptions, QueryHookReturn } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Options of {@link useListStreamQuery}: those of every query hook, with an
|
|
6
|
+
* `execute` that opens the stream.
|
|
7
|
+
*
|
|
8
|
+
* `onSuccess` receives every row once the stream has ended.
|
|
9
|
+
*
|
|
10
|
+
* @template R - One row of the stream: the `data` of each event
|
|
11
|
+
* @template FIELDS - The field names the query may use
|
|
12
|
+
* @template E - The error type, `Error` by default: a failed request
|
|
13
|
+
* rejects with a `FetcherError`, an error event in the stream with a
|
|
14
|
+
* `WowError`
|
|
15
|
+
* @template Q - The query type: `FilterListQuery` by default
|
|
16
|
+
*/
|
|
17
|
+
export interface UseListStreamQueryOptions<R, FIELDS extends string = string, E = Error, Q extends ListQueryRequest<FIELDS> = FilterListQuery<FIELDS>> extends Omit<QueryHookOptions<Q, R[], E>, 'execute'> {
|
|
18
|
+
/** Opens the stream for a query. */
|
|
19
|
+
execute: ListStreamExecutor<R, Q>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* What {@link useListStreamQuery} and `useFetcherListStreamQuery` return: the
|
|
23
|
+
* rows as they arrive, and whether the stream has ended.
|
|
24
|
+
*
|
|
25
|
+
* - `items` — the rows of the current query received so far, in order,
|
|
26
|
+
* updated at most about once a frame (every 16 ms) while they arrive. A new
|
|
27
|
+
* query starts from an empty list; `reset()` empties it; `abort()` and an
|
|
28
|
+
* error keep the rows received before them.
|
|
29
|
+
* - `done` — the stream ended normally and `items` holds every row.
|
|
30
|
+
* - `loading` — from the request until the stream ends, fails or is aborted.
|
|
31
|
+
* - `error` — the request failed (`FetcherError`), or the server sent an error
|
|
32
|
+
* event in the stream (`WowError`, with its `errorCode`).
|
|
33
|
+
* - `status` — `idle`, `loading`, `success` (the same as `done`) or `error`.
|
|
34
|
+
* - `execute()` runs the current query again and aborts the stream in flight;
|
|
35
|
+
* `abort()` stops the stream; `reset()` stops it and empties `items`.
|
|
36
|
+
*/
|
|
37
|
+
export interface UseListStreamQueryReturn<R, FIELDS extends string = string, E = Error, Q extends ListQueryRequest<FIELDS> = FilterListQuery<FIELDS>> extends Omit<QueryHookReturn<Q, R[], E>, 'result'> {
|
|
38
|
+
/**
|
|
39
|
+
* The rows of the current query received so far, a new array at every
|
|
40
|
+
* update.
|
|
41
|
+
*/
|
|
42
|
+
items: R[];
|
|
43
|
+
/** Whether the stream ended normally, so `items` holds every row. */
|
|
44
|
+
done: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Streams the rows of a list query as server-sent events and keeps them as
|
|
48
|
+
* state.
|
|
49
|
+
*
|
|
50
|
+
* The hook owns the stream: it reads it, collects the rows into `items`, and
|
|
51
|
+
* cancels it when a newer query starts, on `abort()` or `reset()`, and on
|
|
52
|
+
* unmount. Components render `items` and never hold a reader, so the hook is
|
|
53
|
+
* safe under StrictMode. `autoExecute` defaults to `true`.
|
|
54
|
+
*
|
|
55
|
+
* Pass a query client method as `execute` — it sends
|
|
56
|
+
* `Accept: text/event-stream` and turns error events into a `WowError` — or
|
|
57
|
+
* use `useFetcherListStreamQuery` with a URL.
|
|
58
|
+
*
|
|
59
|
+
* @template R - One row of the stream: the `data` of each event
|
|
60
|
+
* @template FIELDS - The field names the query may use. With a client whose
|
|
61
|
+
* fields are narrower than `string`, as a generated client's are, pass
|
|
62
|
+
* them here: TypeScript does not infer them from `execute` once `R` is given
|
|
63
|
+
* @template E - The error type
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```tsx
|
|
67
|
+
* import { filter, listQuery, type SnapshotQueryClient } from '@ahoo-wang/wow-client';
|
|
68
|
+
* import { useListStreamQuery } from '@ahoo-wang/wow-react';
|
|
69
|
+
*
|
|
70
|
+
* function PaidOrders({ client }: { client: SnapshotQueryClient<OrderState, OrderFields> }) {
|
|
71
|
+
* const { items, done, loading, error, abort } = useListStreamQuery<OrderState, OrderFields>({
|
|
72
|
+
* initialQuery: listQuery({ filter: filter.eq('state.status', 'PAID') }),
|
|
73
|
+
* execute: (query, attributes, abortController) =>
|
|
74
|
+
* client.listStateStream(query, attributes, abortController),
|
|
75
|
+
* });
|
|
76
|
+
* if (error) return <p role="alert">{error.message}</p>;
|
|
77
|
+
* return (
|
|
78
|
+
* <>
|
|
79
|
+
* <ul>{items.map(order => <li key={order.id}>{order.id}</li>)}</ul>
|
|
80
|
+
* {loading && <button onClick={abort}>Stop</button>}
|
|
81
|
+
* {done && <p>{items.length} orders</p>}
|
|
82
|
+
* </>
|
|
83
|
+
* );
|
|
84
|
+
* }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function useListStreamQuery<R, FIELDS extends string = string, E = Error>(options: UseListStreamQueryOptions<R, FIELDS, E, FilterListQuery<FIELDS>>): UseListStreamQueryReturn<R, FIELDS, E, FilterListQuery<FIELDS>>;
|
|
88
|
+
export declare function useListStreamQuery<R, FIELDS extends string = string, E = Error>(options: UseListStreamQueryOptions<R, FIELDS, E, ListQuery<FIELDS>>): UseListStreamQueryReturn<R, FIELDS, E, ListQuery<FIELDS>>;
|
|
89
|
+
export declare function useListStreamQuery<R, FIELDS extends string = string, E = Error, Q extends ListQueryRequest<FIELDS> = FilterListQuery<FIELDS>>(options: UseListStreamQueryOptions<R, FIELDS, E, Q>): UseListStreamQueryReturn<R, FIELDS, E, Q>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { FilterPagedQuery, PagedList } from '@ahoo-wang/wow-client';
|
|
2
|
+
import { PagedQuery, PagedQueryRequest } from '@ahoo-wang/wow-client/legacy';
|
|
3
|
+
import { QueryHookOptions, QueryHookReturn } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Options of {@link usePagedQuery}: a paged query and an `execute` that
|
|
6
|
+
* resolves to one page.
|
|
7
|
+
*
|
|
8
|
+
* @template R - One row of the page
|
|
9
|
+
* @template FIELDS - The field names the query may use
|
|
10
|
+
* @template E - The error type, `Error` by default
|
|
11
|
+
* @template Q - The query type: `FilterPagedQuery` by default
|
|
12
|
+
*/
|
|
13
|
+
export interface UsePagedQueryOptions<R, FIELDS extends string = string, E = Error, Q extends PagedQueryRequest<FIELDS> = FilterPagedQuery<FIELDS>> extends QueryHookOptions<Q, PagedList<R>, E> {
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* What {@link usePagedQuery} returns: the page (`total` and `list`) as
|
|
17
|
+
* `result`.
|
|
18
|
+
*
|
|
19
|
+
* @template R - One row of the page
|
|
20
|
+
* @template FIELDS - The field names the query may use
|
|
21
|
+
* @template E - The error type, `Error` by default
|
|
22
|
+
* @template Q - The query type: `FilterPagedQuery` by default
|
|
23
|
+
*/
|
|
24
|
+
export interface UsePagedQueryReturn<R, FIELDS extends string = string, E = Error, Q extends PagedQueryRequest<FIELDS> = FilterPagedQuery<FIELDS>> extends QueryHookReturn<Q, PagedList<R>, E> {
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Runs a paged query through your own `execute` function and keeps the page
|
|
28
|
+
* as state: typically a query client's `paged` or `pagedState`.
|
|
29
|
+
*
|
|
30
|
+
* `execute` receives the query, the `attributes` option and an
|
|
31
|
+
* `AbortController`; hand the controller on so that a newer query, `abort()`
|
|
32
|
+
* or an unmount cancels the request. The query runs on mount and whenever
|
|
33
|
+
* `query` or `setQuery()` changes it — turn pages with `setQuery()`; set
|
|
34
|
+
* `autoExecute: false` to run it only through `execute()`.
|
|
35
|
+
*
|
|
36
|
+
* Returns `result` (`{ total, list }`, or `undefined` before the first
|
|
37
|
+
* success), `loading`, `error`, `status`, `execute`, `abort`, `reset`,
|
|
38
|
+
* `getQuery` and `setQuery`.
|
|
39
|
+
*
|
|
40
|
+
* @template R - One row of the page
|
|
41
|
+
* @template FIELDS - The field names the query may use. With a client whose
|
|
42
|
+
* fields are narrower than `string`, as a generated client's are, pass
|
|
43
|
+
* them here: TypeScript does not infer them from `execute` once `R` is given
|
|
44
|
+
* @template E - The error type, `Error` by default
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```tsx
|
|
48
|
+
* import { filter, pagedQuery, type SnapshotQueryClient } from '@ahoo-wang/wow-client';
|
|
49
|
+
* import { usePagedQuery } from '@ahoo-wang/wow-react';
|
|
50
|
+
*
|
|
51
|
+
* function PaidOrders({ client, page }: { client: SnapshotQueryClient<OrderState, OrderFields>; page: number }) {
|
|
52
|
+
* const { result, loading, error } = usePagedQuery<OrderState, OrderFields>({
|
|
53
|
+
* query: pagedQuery({
|
|
54
|
+
* filter: filter.eq('state.status', 'PAID'),
|
|
55
|
+
* pagination: { index: page, size: 20 },
|
|
56
|
+
* }),
|
|
57
|
+
* execute: (query, attributes, abortController) =>
|
|
58
|
+
* client.pagedState(query, attributes, abortController),
|
|
59
|
+
* });
|
|
60
|
+
* if (error) return <p role="alert">{error.message}</p>;
|
|
61
|
+
* if (loading || !result) return <p>Loading…</p>;
|
|
62
|
+
* return <p>{result.list.length} of {result.total}</p>;
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare function usePagedQuery<R, FIELDS extends string = string, E = Error>(options: UsePagedQueryOptions<R, FIELDS, E, FilterPagedQuery<FIELDS>>): UsePagedQueryReturn<R, FIELDS, E, FilterPagedQuery<FIELDS>>;
|
|
67
|
+
export declare function usePagedQuery<R, FIELDS extends string = string, E = Error>(options: UsePagedQueryOptions<R, FIELDS, E, PagedQuery<FIELDS>>): UsePagedQueryReturn<R, FIELDS, E, PagedQuery<FIELDS>>;
|
|
68
|
+
export declare function usePagedQuery<R, FIELDS extends string = string, E = Error, Q extends PagedQueryRequest<FIELDS> = FilterPagedQuery<FIELDS>>(options: UsePagedQueryOptions<R, FIELDS, E, Q>): UsePagedQueryReturn<R, FIELDS, E, Q>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { FilterSingleQuery } from '@ahoo-wang/wow-client';
|
|
2
|
+
import { SingleQuery, SingleQueryRequest } from '@ahoo-wang/wow-client/legacy';
|
|
3
|
+
import { QueryHookOptions, QueryHookReturn } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Options of {@link useSingleQuery}: a single query and an `execute` that
|
|
6
|
+
* resolves to one item.
|
|
7
|
+
*
|
|
8
|
+
* @template R - The item the query returns
|
|
9
|
+
* @template FIELDS - The field names the query may use
|
|
10
|
+
* @template E - The error type, `Error` by default
|
|
11
|
+
* @template Q - The query type: `FilterSingleQuery` by default
|
|
12
|
+
*/
|
|
13
|
+
export interface UseSingleQueryOptions<R, FIELDS extends string = string, E = Error, Q extends SingleQueryRequest<FIELDS> = FilterSingleQuery<FIELDS>> extends QueryHookOptions<Q, R, E> {
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* What {@link useSingleQuery} returns: the item as `result`.
|
|
17
|
+
*
|
|
18
|
+
* @template R - The item the query returns
|
|
19
|
+
* @template FIELDS - The field names the query may use
|
|
20
|
+
* @template E - The error type, `Error` by default
|
|
21
|
+
* @template Q - The query type: `FilterSingleQuery` by default
|
|
22
|
+
*/
|
|
23
|
+
export interface UseSingleQueryReturn<R, FIELDS extends string = string, E = Error, Q extends SingleQueryRequest<FIELDS> = FilterSingleQuery<FIELDS>> extends QueryHookReturn<Q, R, E> {
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Runs a single query through your own `execute` function and keeps the
|
|
27
|
+
* result as state: typically a query client's `single` or `singleState`.
|
|
28
|
+
*
|
|
29
|
+
* `execute` receives the query, the `attributes` option and an
|
|
30
|
+
* `AbortController`; hand the controller on so that a newer query, `abort()`
|
|
31
|
+
* or an unmount cancels the request. The query runs on mount and whenever
|
|
32
|
+
* `query` or `setQuery()` changes it; set `autoExecute: false` to run it only
|
|
33
|
+
* through `execute()`.
|
|
34
|
+
*
|
|
35
|
+
* Returns `result` (the item, or `undefined` before the first success),
|
|
36
|
+
* `loading`, `error`, `status`, `execute`, `abort`, `reset`, `getQuery` and
|
|
37
|
+
* `setQuery`.
|
|
38
|
+
*
|
|
39
|
+
* @template R - The item the query returns
|
|
40
|
+
* @template FIELDS - The field names the query may use. With a client whose
|
|
41
|
+
* fields are narrower than `string`, as a generated client's are, pass
|
|
42
|
+
* them here: TypeScript does not infer them from `execute` once `R` is given
|
|
43
|
+
* @template E - The error type, `Error` by default
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```tsx
|
|
47
|
+
* import { filter, singleQuery, type SnapshotQueryClient } from '@ahoo-wang/wow-client';
|
|
48
|
+
* import { useSingleQuery } from '@ahoo-wang/wow-react';
|
|
49
|
+
*
|
|
50
|
+
* function OrderStatus({ client, id }: { client: SnapshotQueryClient<OrderState, OrderFields>; id: string }) {
|
|
51
|
+
* const { result, loading, error } = useSingleQuery<OrderState, OrderFields>({
|
|
52
|
+
* query: singleQuery({ filter: filter.id(id) }),
|
|
53
|
+
* execute: (query, attributes, abortController) =>
|
|
54
|
+
* client.singleState(query, attributes, abortController),
|
|
55
|
+
* });
|
|
56
|
+
* if (error) return <p role="alert">{error.message}</p>;
|
|
57
|
+
* if (loading || !result) return <p>Loading…</p>;
|
|
58
|
+
* return <p>{result.status}</p>;
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function useSingleQuery<R, FIELDS extends string = string, E = Error>(options: UseSingleQueryOptions<R, FIELDS, E, FilterSingleQuery<FIELDS>>): UseSingleQueryReturn<R, FIELDS, E, FilterSingleQuery<FIELDS>>;
|
|
63
|
+
export declare function useSingleQuery<R, FIELDS extends string = string, E = Error>(options: UseSingleQueryOptions<R, FIELDS, E, SingleQuery<FIELDS>>): UseSingleQueryReturn<R, FIELDS, E, SingleQuery<FIELDS>>;
|
|
64
|
+
export declare function useSingleQuery<R, FIELDS extends string = string, E = Error, Q extends SingleQueryRequest<FIELDS> = FilterSingleQuery<FIELDS>>(options: UseSingleQueryOptions<R, FIELDS, E, Q>): UseSingleQueryReturn<R, FIELDS, E, Q>;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './hooks/useCountQuery.js';
|
|
2
|
+
export * from './hooks/useFetcherCountQuery.js';
|
|
3
|
+
export * from './hooks/useFetcherListQuery.js';
|
|
4
|
+
export * from './hooks/useFetcherListStreamQuery.js';
|
|
5
|
+
export * from './hooks/useFetcherPagedQuery.js';
|
|
6
|
+
export * from './hooks/useFetcherSingleQuery.js';
|
|
7
|
+
export * from './hooks/useListQuery.js';
|
|
8
|
+
export * from './hooks/useListStreamQuery.js';
|
|
9
|
+
export * from './hooks/usePagedQuery.js';
|
|
10
|
+
export * from './hooks/useSingleQuery.js';
|
|
11
|
+
export * from './types.js';
|
package/dist/index.es.js
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { dequal as e } from "dequal";
|
|
2
|
+
import { useCallback as t, useEffect as n, useLayoutEffect as r, useRef as i, useState as a } from "react";
|
|
3
|
+
import { c as o } from "react/compiler-runtime";
|
|
4
|
+
import { DEFAULT_FETCHER_NAME as s, JsonResultExtractor as c, getFetcher as l } from "@ahoo-wang/fetcher";
|
|
5
|
+
import { QUERY_STREAM_ENDPOINT as u } from "@ahoo-wang/wow-client";
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/internal/queryTransitions.ts
|
|
8
|
+
function initialQueryState(e) {
|
|
9
|
+
return {
|
|
10
|
+
status: e ? "loading" : "idle",
|
|
11
|
+
result: void 0,
|
|
12
|
+
error: void 0
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function queryTransition(e, t) {
|
|
16
|
+
switch (t.type) {
|
|
17
|
+
case "start": return {
|
|
18
|
+
status: "loading",
|
|
19
|
+
result: e.result,
|
|
20
|
+
error: void 0
|
|
21
|
+
};
|
|
22
|
+
case "succeed": return {
|
|
23
|
+
status: "success",
|
|
24
|
+
result: t.result,
|
|
25
|
+
error: void 0
|
|
26
|
+
};
|
|
27
|
+
case "fail": return {
|
|
28
|
+
status: "error",
|
|
29
|
+
result: e.result,
|
|
30
|
+
error: t.error
|
|
31
|
+
};
|
|
32
|
+
case "abort": return {
|
|
33
|
+
status: "idle",
|
|
34
|
+
result: e.result,
|
|
35
|
+
error: void 0
|
|
36
|
+
};
|
|
37
|
+
case "reset": return {
|
|
38
|
+
status: "idle",
|
|
39
|
+
result: void 0,
|
|
40
|
+
error: void 0
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/internal/useQueryRunner.ts
|
|
46
|
+
function useContentStable(t) {
|
|
47
|
+
let [n, r] = a(t);
|
|
48
|
+
return n === t || e(n, t) ? n : (r(t), t);
|
|
49
|
+
}
|
|
50
|
+
async function notify(e, t, n) {
|
|
51
|
+
try {
|
|
52
|
+
await t?.(n);
|
|
53
|
+
} catch (t) {
|
|
54
|
+
console.warn(`wow-react: ${e} threw`, t);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function isAbortError(e) {
|
|
58
|
+
return e instanceof Error && e.name === "AbortError";
|
|
59
|
+
}
|
|
60
|
+
function useQueryRunner(e, o, s = !0) {
|
|
61
|
+
let c = e.autoExecute ?? !0, l = useContentStable(e.query), [u, d] = a(() => initialQueryState(c && (e.query ?? e.initialQuery) !== void 0)), f = i(e), p = i(e.query ?? e.initialQuery), m = i({ id: 0 }), h = i(!1);
|
|
62
|
+
r(() => {
|
|
63
|
+
f.current = e;
|
|
64
|
+
});
|
|
65
|
+
let g = t((e, t) => !h.current || m.current.id !== e ? !1 : (d((e) => queryTransition(e, t)), !0), []), _ = t(() => {
|
|
66
|
+
let { controller: e } = m.current;
|
|
67
|
+
m.current = { id: m.current.id + 1 }, e?.abort();
|
|
68
|
+
}, []), v = t(async () => {
|
|
69
|
+
let e = p.current;
|
|
70
|
+
if (!h.current || e === void 0) return;
|
|
71
|
+
m.current.controller?.abort();
|
|
72
|
+
let t = new AbortController(), n = m.current.id + 1;
|
|
73
|
+
m.current = {
|
|
74
|
+
id: n,
|
|
75
|
+
controller: t
|
|
76
|
+
}, d((e) => queryTransition(e, { type: "start" }));
|
|
77
|
+
let { execute: r, attributes: i } = f.current;
|
|
78
|
+
try {
|
|
79
|
+
let a = await r(e, i, t);
|
|
80
|
+
t.signal.aborted ? g(n, { type: "abort" }) : g(n, {
|
|
81
|
+
type: "succeed",
|
|
82
|
+
result: s ? a : void 0
|
|
83
|
+
}) && await notify("onSuccess", f.current.onSuccess, a);
|
|
84
|
+
} catch (e) {
|
|
85
|
+
t.signal.aborted || isAbortError(e) ? g(n, { type: "abort" }) : g(n, {
|
|
86
|
+
type: "fail",
|
|
87
|
+
error: e
|
|
88
|
+
}) && await notify("onError", f.current.onError, e);
|
|
89
|
+
} finally {
|
|
90
|
+
m.current.controller === t && (m.current = { id: m.current.id });
|
|
91
|
+
}
|
|
92
|
+
}, [g, s]), y = t(() => {
|
|
93
|
+
_(), d((e) => queryTransition(e, { type: "abort" }));
|
|
94
|
+
}, [_]), b = t(() => {
|
|
95
|
+
_(), d((e) => queryTransition(e, { type: "reset" }));
|
|
96
|
+
}, [_]), x = t(() => p.current, []), S = t((e) => {
|
|
97
|
+
p.current = e, (f.current.autoExecute ?? !0) && v();
|
|
98
|
+
}, [v]);
|
|
99
|
+
n(() => (h.current = !0, () => {
|
|
100
|
+
h.current = !1, _();
|
|
101
|
+
}), [_]);
|
|
102
|
+
let C = i(l);
|
|
103
|
+
return n(() => {
|
|
104
|
+
let e = l === void 0 && C.current !== void 0;
|
|
105
|
+
if (C.current = l, e) {
|
|
106
|
+
p.current = void 0, y();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
l !== void 0 && (p.current = l), c && v();
|
|
110
|
+
}, [
|
|
111
|
+
l,
|
|
112
|
+
o,
|
|
113
|
+
c,
|
|
114
|
+
v,
|
|
115
|
+
y
|
|
116
|
+
]), {
|
|
117
|
+
status: u.status,
|
|
118
|
+
loading: u.status === "loading",
|
|
119
|
+
result: u.result,
|
|
120
|
+
error: u.error,
|
|
121
|
+
execute: v,
|
|
122
|
+
abort: y,
|
|
123
|
+
reset: b,
|
|
124
|
+
getQuery: x,
|
|
125
|
+
setQuery: S
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
//#endregion
|
|
129
|
+
//#region src/hooks/useCountQuery.ts
|
|
130
|
+
function useCountQuery(e) {
|
|
131
|
+
return useQueryRunner(e);
|
|
132
|
+
}
|
|
133
|
+
//#endregion
|
|
134
|
+
//#region src/internal/endpoint.ts
|
|
135
|
+
function postQuery({ url: e, fetcher: t }) {
|
|
136
|
+
return (n, r, i) => l(t).post(e, {
|
|
137
|
+
body: n,
|
|
138
|
+
abortController: i
|
|
139
|
+
}, {
|
|
140
|
+
attributes: r,
|
|
141
|
+
resultExtractor: c
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
function postQueryStream({ url: e, fetcher: t }) {
|
|
145
|
+
return (n, r, i) => l(t).post(e, {
|
|
146
|
+
body: n,
|
|
147
|
+
headers: { ...u.headers },
|
|
148
|
+
abortController: i
|
|
149
|
+
}, {
|
|
150
|
+
attributes: r,
|
|
151
|
+
resultExtractor: u.resultExtractor
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
function endpointIdentity({ url: e, fetcher: t }) {
|
|
155
|
+
let n;
|
|
156
|
+
return n = t === void 0 ? `name:${s}` : typeof t == "string" ? `name:${t}` : "name" in t && typeof t.name == "string" ? `name:${t.name}` : `baseURL:${t.urlBuilder.baseURL}`, JSON.stringify([e, n]);
|
|
157
|
+
}
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region src/internal/useEndpointRunner.ts
|
|
160
|
+
function useEndpointRunner(e) {
|
|
161
|
+
let t = o(13), n, r, i;
|
|
162
|
+
t[0] === e ? (n = t[1], r = t[2], i = t[3]) : ({url: i, fetcher: n, ...r} = e, t[0] = e, t[1] = n, t[2] = r, t[3] = i);
|
|
163
|
+
let a;
|
|
164
|
+
t[4] !== n || t[5] !== i ? (a = postQuery({
|
|
165
|
+
url: i,
|
|
166
|
+
fetcher: n
|
|
167
|
+
}), t[4] = n, t[5] = i, t[6] = a) : a = t[6];
|
|
168
|
+
let s;
|
|
169
|
+
t[7] !== r || t[8] !== a ? (s = {
|
|
170
|
+
...r,
|
|
171
|
+
execute: a
|
|
172
|
+
}, t[7] = r, t[8] = a, t[9] = s) : s = t[9];
|
|
173
|
+
let c;
|
|
174
|
+
return t[10] !== n || t[11] !== i ? (c = endpointIdentity({
|
|
175
|
+
url: i,
|
|
176
|
+
fetcher: n
|
|
177
|
+
}), t[10] = n, t[11] = i, t[12] = c) : c = t[12], useQueryRunner(s, c);
|
|
178
|
+
}
|
|
179
|
+
//#endregion
|
|
180
|
+
//#region src/hooks/useFetcherCountQuery.ts
|
|
181
|
+
function useFetcherCountQuery(e) {
|
|
182
|
+
return useEndpointRunner(e);
|
|
183
|
+
}
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region src/hooks/useFetcherListQuery.ts
|
|
186
|
+
function useFetcherListQuery(e) {
|
|
187
|
+
return useEndpointRunner(e);
|
|
188
|
+
}
|
|
189
|
+
async function readStreamRows(e, t, n) {
|
|
190
|
+
let r = e.getReader(), i = [], a = 0, o = -Infinity, s, flush = () => {
|
|
191
|
+
s !== void 0 && clearTimeout(s), s = void 0, !(t.aborted || a === i.length) && (a = i.length, o = Date.now(), n(i.slice()));
|
|
192
|
+
}, schedule = () => {
|
|
193
|
+
if (s !== void 0) return;
|
|
194
|
+
let e = Math.max(0, o + 16 - Date.now());
|
|
195
|
+
s = setTimeout(flush, e);
|
|
196
|
+
}, cancel = () => {
|
|
197
|
+
r.cancel(t.reason).catch(() => {});
|
|
198
|
+
};
|
|
199
|
+
t.aborted ? cancel() : t.addEventListener("abort", cancel, { once: !0 });
|
|
200
|
+
try {
|
|
201
|
+
for (;;) {
|
|
202
|
+
let { done: e, value: t } = await r.read();
|
|
203
|
+
if (e) break;
|
|
204
|
+
i.push(t), schedule();
|
|
205
|
+
}
|
|
206
|
+
return flush(), i;
|
|
207
|
+
} catch (e) {
|
|
208
|
+
throw flush(), e;
|
|
209
|
+
} finally {
|
|
210
|
+
s !== void 0 && clearTimeout(s), t.removeEventListener("abort", cancel), r.releaseLock();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
//#endregion
|
|
214
|
+
//#region src/internal/useListStream.ts
|
|
215
|
+
function useListStream(e, t) {
|
|
216
|
+
let n = o(18), [r, i] = a(_temp), s = e.execute, t0;
|
|
217
|
+
n[0] === s ? t0 = n[1] : (t0 = async (e, t, n) => (i([]), readStreamRows(await s(e, t, n), n.signal, i)), n[0] = s, n[1] = t0);
|
|
218
|
+
let c;
|
|
219
|
+
n[2] !== e || n[3] !== t0 ? (c = {
|
|
220
|
+
...e,
|
|
221
|
+
execute: t0
|
|
222
|
+
}, n[2] = e, n[3] = t0, n[4] = c) : c = n[4];
|
|
223
|
+
let { status: l, loading: u, error: d, execute: f, abort: p, reset: m, getQuery: h, setQuery: g } = useQueryRunner(c, t, !1), t2;
|
|
224
|
+
n[5] === m ? t2 = n[6] : (t2 = () => {
|
|
225
|
+
m(), i([]);
|
|
226
|
+
}, n[5] = m, n[6] = t2);
|
|
227
|
+
let _ = t2, v = l === "success", y;
|
|
228
|
+
return n[7] !== p || n[8] !== d || n[9] !== f || n[10] !== h || n[11] !== r || n[12] !== u || n[13] !== _ || n[14] !== g || n[15] !== l || n[16] !== v ? (y = {
|
|
229
|
+
items: r,
|
|
230
|
+
done: v,
|
|
231
|
+
loading: u,
|
|
232
|
+
error: d,
|
|
233
|
+
status: l,
|
|
234
|
+
execute: f,
|
|
235
|
+
abort: p,
|
|
236
|
+
reset: _,
|
|
237
|
+
getQuery: h,
|
|
238
|
+
setQuery: g
|
|
239
|
+
}, n[7] = p, n[8] = d, n[9] = f, n[10] = h, n[11] = r, n[12] = u, n[13] = _, n[14] = g, n[15] = l, n[16] = v, n[17] = y) : y = n[17], y;
|
|
240
|
+
}
|
|
241
|
+
function _temp() {
|
|
242
|
+
return [];
|
|
243
|
+
}
|
|
244
|
+
//#endregion
|
|
245
|
+
//#region src/hooks/useFetcherListStreamQuery.ts
|
|
246
|
+
function useFetcherListStreamQuery(e) {
|
|
247
|
+
let t = o(13), n, r, i;
|
|
248
|
+
t[0] === e ? (n = t[1], r = t[2], i = t[3]) : ({url: i, fetcher: n, ...r} = e, t[0] = e, t[1] = n, t[2] = r, t[3] = i);
|
|
249
|
+
let a;
|
|
250
|
+
t[4] !== n || t[5] !== i ? (a = postQueryStream({
|
|
251
|
+
url: i,
|
|
252
|
+
fetcher: n
|
|
253
|
+
}), t[4] = n, t[5] = i, t[6] = a) : a = t[6];
|
|
254
|
+
let s;
|
|
255
|
+
t[7] !== r || t[8] !== a ? (s = {
|
|
256
|
+
...r,
|
|
257
|
+
execute: a
|
|
258
|
+
}, t[7] = r, t[8] = a, t[9] = s) : s = t[9];
|
|
259
|
+
let c;
|
|
260
|
+
return t[10] !== n || t[11] !== i ? (c = endpointIdentity({
|
|
261
|
+
url: i,
|
|
262
|
+
fetcher: n
|
|
263
|
+
}), t[10] = n, t[11] = i, t[12] = c) : c = t[12], useListStream(s, c);
|
|
264
|
+
}
|
|
265
|
+
//#endregion
|
|
266
|
+
//#region src/hooks/useFetcherPagedQuery.ts
|
|
267
|
+
function useFetcherPagedQuery(e) {
|
|
268
|
+
return useEndpointRunner(e);
|
|
269
|
+
}
|
|
270
|
+
//#endregion
|
|
271
|
+
//#region src/hooks/useFetcherSingleQuery.ts
|
|
272
|
+
function useFetcherSingleQuery(e) {
|
|
273
|
+
return useEndpointRunner(e);
|
|
274
|
+
}
|
|
275
|
+
//#endregion
|
|
276
|
+
//#region src/hooks/useListQuery.ts
|
|
277
|
+
function useListQuery(e) {
|
|
278
|
+
return useQueryRunner(e);
|
|
279
|
+
}
|
|
280
|
+
//#endregion
|
|
281
|
+
//#region src/hooks/useListStreamQuery.ts
|
|
282
|
+
function useListStreamQuery(e) {
|
|
283
|
+
return useListStream(e);
|
|
284
|
+
}
|
|
285
|
+
//#endregion
|
|
286
|
+
//#region src/hooks/usePagedQuery.ts
|
|
287
|
+
function usePagedQuery(e) {
|
|
288
|
+
return useQueryRunner(e);
|
|
289
|
+
}
|
|
290
|
+
//#endregion
|
|
291
|
+
//#region src/hooks/useSingleQuery.ts
|
|
292
|
+
function useSingleQuery(e) {
|
|
293
|
+
return useQueryRunner(e);
|
|
294
|
+
}
|
|
295
|
+
//#endregion
|
|
296
|
+
export { useCountQuery, useFetcherCountQuery, useFetcherListQuery, useFetcherListStreamQuery, useFetcherPagedQuery, useFetcherSingleQuery, useListQuery, useListStreamQuery, usePagedQuery, useSingleQuery };
|
|
297
|
+
|
|
298
|
+
//# sourceMappingURL=index.es.js.map
|