@raf-query/core 0.11.1 → 0.13.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/CHANGELOG.md +39 -1
- package/README.md +28 -18
- package/dist/client.d.mts +163 -119
- package/dist/client.mjs +90 -162
- package/dist/entry.d.mts +73 -147
- package/dist/entry.mjs +314 -471
- package/dist/features/focus-refetch/focus-refetch.d.mts +17 -0
- package/dist/features/focus-refetch/focus-refetch.mjs +20 -0
- package/dist/features/polling/polling.d.mts +16 -0
- package/dist/features/polling/polling.mjs +39 -0
- package/dist/features/reconnect-refetch/reconnect-refetch.d.mts +17 -0
- package/dist/features/reconnect-refetch/reconnect-refetch.mjs +16 -0
- package/dist/features/shared.mjs +13 -0
- package/dist/guards.mjs +23 -0
- package/dist/hydration/hydration.d.mts +108 -0
- package/dist/hydration/hydration.mjs +142 -0
- package/dist/index.d.mts +19 -13
- package/dist/index.mjs +16 -13
- package/dist/infinite/infinite.d.mts +83 -0
- package/dist/infinite/infinite.mjs +120 -0
- package/dist/infinite/paging.d.mts +71 -0
- package/dist/infinite/paging.mjs +62 -0
- package/dist/internal.d.mts +13 -0
- package/dist/internal.mjs +7 -0
- package/dist/keys/keys.d.mts +54 -0
- package/dist/keys/keys.mjs +53 -0
- package/dist/keys/targets.d.mts +62 -0
- package/dist/keys/targets.mjs +85 -0
- package/dist/links/retry/retry.d.mts +33 -0
- package/dist/links/retry/retry.mjs +53 -0
- package/dist/links/timeout/timeout.d.mts +17 -0
- package/dist/links/timeout/timeout.mjs +35 -0
- package/dist/load.d.mts +149 -0
- package/dist/load.mjs +179 -0
- package/dist/options.d.mts +161 -332
- package/dist/options.mjs +28 -40
- package/dist/presets.d.mts +35 -0
- package/dist/presets.mjs +27 -0
- package/dist/root.d.mts +86 -0
- package/dist/structural-sharing/structural-sharing.mjs +32 -0
- package/dist/subscribe.d.mts +15 -0
- package/dist/subscribe.mjs +29 -0
- package/dist/thenable.d.mts +15 -17
- package/dist/thenable.mjs +25 -6
- package/dist/verbs.d.mts +150 -0
- package/dist/verbs.mjs +115 -0
- package/package.json +13 -9
- package/dist/_virtual/_rolldown/runtime.mjs +0 -13
- package/dist/all-keyed.d.mts +0 -18
- package/dist/all-keyed.mjs +0 -19
- package/dist/binding.d.mts +0 -92
- package/dist/binding.mjs +0 -186
- package/dist/cache.d.mts +0 -164
- package/dist/cache.mjs +0 -184
- package/dist/controls.d.mts +0 -95
- package/dist/controls.mjs +0 -70
- package/dist/hydration.d.mts +0 -84
- package/dist/hydration.mjs +0 -148
- package/dist/infinite.d.mts +0 -5
- package/dist/infinite.mjs +0 -103
- package/dist/key.d.mts +0 -18
- package/dist/key.mjs +0 -36
- package/dist/listen.mjs +0 -19
- package/dist/notify.mjs +0 -21
- package/dist/observer.d.mts +0 -110
- package/dist/observer.mjs +0 -300
- package/dist/platform.d.mts +0 -27
- package/dist/platform.mjs +0 -44
- package/dist/query.d.mts +0 -137
- package/dist/query.mjs +0 -147
- package/dist/request.mjs +0 -47
- package/dist/retry.mjs +0 -25
- package/dist/share.mjs +0 -40
package/dist/load.d.mts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { DataOf, InputArgs, InputOf, KeyOf, QueryFactory } from "./options.mjs";
|
|
2
|
+
import { Entry } from "./entry.mjs";
|
|
3
|
+
import { QueryClient } from "./client.mjs";
|
|
4
|
+
//#region src/load.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* A small serializable reference to a query: its key and its factory's
|
|
7
|
+
* input. It carries no data; readers get that from the cache. Handles of
|
|
8
|
+
* different factories have different types.
|
|
9
|
+
*
|
|
10
|
+
* @see https://raf-query.katt.dev/docs/reading-queries#handles
|
|
11
|
+
*/
|
|
12
|
+
export interface QueryHandle<TFactory extends QueryFactory = QueryFactory> {
|
|
13
|
+
readonly input: InputOf<TFactory>;
|
|
14
|
+
readonly queryKey: KeyOf<TFactory>;
|
|
15
|
+
}
|
|
16
|
+
type LoadKind = "prefetch" | "revalidate" | "swr";
|
|
17
|
+
/**
|
|
18
|
+
* A query for `load` to start. Building one starts nothing.
|
|
19
|
+
*
|
|
20
|
+
* @see https://raf-query.katt.dev/docs/starting-queries
|
|
21
|
+
*/
|
|
22
|
+
export interface LoadEntry<TFactory extends QueryFactory = QueryFactory, TKind extends LoadKind = LoadKind> {
|
|
23
|
+
readonly factory: TFactory;
|
|
24
|
+
readonly input: InputOf<TFactory>;
|
|
25
|
+
readonly kind: TKind;
|
|
26
|
+
/** For paged factories: how many pages a first load fetches. */
|
|
27
|
+
readonly pages?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Options for a `load` entry.
|
|
31
|
+
*
|
|
32
|
+
* @see https://raf-query.katt.dev/docs/infinite-queries#loading-several-pages-up-front
|
|
33
|
+
*/
|
|
34
|
+
export interface LoadEntryOptions {
|
|
35
|
+
/** For paged factories: how many pages a first load fetches. Default 1. */
|
|
36
|
+
readonly pages?: number;
|
|
37
|
+
}
|
|
38
|
+
type LoadEntryArgs<TFactory extends QueryFactory> = [input: InputOf<TFactory>, options?: LoadEntryOptions] | InputArgs<TFactory>;
|
|
39
|
+
/**
|
|
40
|
+
* Start the query if the cache has no fresh data, and don't wait for it.
|
|
41
|
+
* It never makes the load reject: errors show up where a component reads
|
|
42
|
+
* the handle.
|
|
43
|
+
*
|
|
44
|
+
* @see https://raf-query.katt.dev/docs/starting-queries#prefetch-or-swr
|
|
45
|
+
*/
|
|
46
|
+
export declare function prefetch<TFactory extends QueryFactory>(factory: TFactory, ...args: LoadEntryArgs<TFactory>): LoadEntry<TFactory, "prefetch">;
|
|
47
|
+
/**
|
|
48
|
+
* Use cached data even when it's stale, and wait only when the cache has
|
|
49
|
+
* none. Stale data resolves at once and refetches in the background, as
|
|
50
|
+
* HTTP's
|
|
51
|
+
* [`stale-while-revalidate`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#stale-while-revalidate)
|
|
52
|
+
* does. The load rejects if the fetch it waits for fails.
|
|
53
|
+
*
|
|
54
|
+
* @see https://raf-query.katt.dev/docs/starting-queries#prefetch-or-swr
|
|
55
|
+
*/
|
|
56
|
+
export declare function swr<TFactory extends QueryFactory>(factory: TFactory, ...args: LoadEntryArgs<TFactory>): LoadEntry<TFactory, "swr">;
|
|
57
|
+
/**
|
|
58
|
+
* Wait for fresh data, as HTTP's
|
|
59
|
+
* [`must-revalidate`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#must-revalidate)
|
|
60
|
+
* does. Fresh cached data resolves at once without a refetch (`staleTime`
|
|
61
|
+
* is the max-age); with stale data or none it waits for the fetch. On a
|
|
62
|
+
* server client, data counts as fresh until a write invalidates it. The
|
|
63
|
+
* load rejects if the fetch fails.
|
|
64
|
+
*
|
|
65
|
+
* @see https://raf-query.katt.dev/docs/starting-queries#the-three-entries
|
|
66
|
+
*/
|
|
67
|
+
export declare function revalidate<TFactory extends QueryFactory>(factory: TFactory, ...args: LoadEntryArgs<TFactory>): LoadEntry<TFactory, "revalidate">;
|
|
68
|
+
/**
|
|
69
|
+
* In place of a `load` entry: skip the query. Its handle is `undefined` and
|
|
70
|
+
* `data` has no key for it, so a component renders its reader only when
|
|
71
|
+
* there's a handle.
|
|
72
|
+
*
|
|
73
|
+
* ```ts
|
|
74
|
+
* const [handles] = await load(queryClient, {
|
|
75
|
+
* drafts: user.isAdmin ? prefetch(draftsQuery, { slug }) : skipToken,
|
|
76
|
+
* });
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* @see https://raf-query.katt.dev/docs/starting-queries#conditional-queries
|
|
80
|
+
*/
|
|
81
|
+
export declare const skipToken: unique symbol;
|
|
82
|
+
/** What `load` takes per name: an entry, or `skipToken`. */
|
|
83
|
+
type LoadEntries = Record<string, LoadEntry | typeof skipToken>;
|
|
84
|
+
type HandleOf<TEntry> = TEntry extends LoadEntry ? QueryHandle<TEntry["factory"]> : undefined;
|
|
85
|
+
type DataOfEntry<TEntry> = TEntry extends LoadEntry ? DataOf<TEntry["factory"]> : never;
|
|
86
|
+
type LoadedData<TEntries extends LoadEntries> = { [TName in keyof TEntries as TEntries[TName] extends LoadEntry<QueryFactory, "revalidate" | "swr"> ? TName : never]: DataOfEntry<TEntries[TName]>; };
|
|
87
|
+
/**
|
|
88
|
+
* What `load` resolves to: a handle per entry (`undefined` for `skipToken`),
|
|
89
|
+
* and the data of `swr` and `revalidate` entries.
|
|
90
|
+
*
|
|
91
|
+
* @see https://raf-query.katt.dev/docs/starting-queries
|
|
92
|
+
*/
|
|
93
|
+
export type Loaded<TEntries extends LoadEntries> = readonly [handles: { [TName in keyof TEntries]: HandleOf<TEntries[TName]>; }, data: LoadedData<TEntries>];
|
|
94
|
+
/** A `load` call as devtools show it. */
|
|
95
|
+
export interface LoadRecord {
|
|
96
|
+
readonly entries: ReadonlyArray<{
|
|
97
|
+
readonly hash: string;
|
|
98
|
+
readonly kind: LoadKind;
|
|
99
|
+
readonly name: string;
|
|
100
|
+
}>;
|
|
101
|
+
readonly startedAt: number;
|
|
102
|
+
}
|
|
103
|
+
/** The latest `load` calls on a client, newest last. Recorded in development only. */
|
|
104
|
+
export declare function loadsOf(client: QueryClient): ReadonlyArray<LoadRecord>;
|
|
105
|
+
/** Read an entry's data the way its readers see it: through `select`. */
|
|
106
|
+
export declare function readData(entry: Entry): unknown;
|
|
107
|
+
/** Start the entry's request if its data isn't fresh. Never waits. */
|
|
108
|
+
export declare function startIfStale(entry: Entry): void;
|
|
109
|
+
/**
|
|
110
|
+
* Start a loader's queries and return a serializable handle for each. It
|
|
111
|
+
* starts every entry before it waits for any, so the order of the entries
|
|
112
|
+
* can't create a waterfall. Resolves with `[handles, data]` once every
|
|
113
|
+
* `swr` and `revalidate` entry has data, and rejects with the error as soon
|
|
114
|
+
* as one fails.
|
|
115
|
+
* `prefetch` entries never make it reject. A `skipToken` in place of an
|
|
116
|
+
* entry starts nothing and gets no handle.
|
|
117
|
+
*
|
|
118
|
+
* ```ts
|
|
119
|
+
* const [handles, data] = await load(queryClient, {
|
|
120
|
+
* comments: prefetch(commentsQuery, { slug }),
|
|
121
|
+
* post: swr(postQuery, { slug }),
|
|
122
|
+
* });
|
|
123
|
+
* ```
|
|
124
|
+
*
|
|
125
|
+
* @see https://raf-query.katt.dev/docs/starting-queries
|
|
126
|
+
*/
|
|
127
|
+
export declare function load<const TEntries extends LoadEntries>(client: QueryClient, entries: TEntries): Promise<Loaded<TEntries>>;
|
|
128
|
+
/** Whether a handle came from `waterfallHandle()`: reading it is expected to fetch. */
|
|
129
|
+
export declare function isWaterfallHandle(handle: Pick<QueryHandle, "queryKey">): boolean;
|
|
130
|
+
/**
|
|
131
|
+
* The handle of a query whose input is only known while rendering, like an
|
|
132
|
+
* id in another query's data. It starts nothing: the component that reads
|
|
133
|
+
* it fetches when it renders, which makes it a request waterfall, and the
|
|
134
|
+
* name keeps that visible. Prefer starting queries in a loader with `load`.
|
|
135
|
+
*
|
|
136
|
+
* With a handle and an updater, it derives a handle from that one: the
|
|
137
|
+
* updater gets the handle's input and returns the new one (say, with a
|
|
138
|
+
* search term being typed). While the new input maps to the same query, it
|
|
139
|
+
* returns the handle as is, so readers keep it.
|
|
140
|
+
*
|
|
141
|
+
* ```ts
|
|
142
|
+
* const searchHandle = waterfallHandle(searchQuery, props.search, (input) => ({ ...input, q }));
|
|
143
|
+
* ```
|
|
144
|
+
*
|
|
145
|
+
* @see https://raf-query.katt.dev/docs/request-waterfalls#render-time-inputs-waterfallhandle
|
|
146
|
+
*/
|
|
147
|
+
export declare function waterfallHandle<TFactory extends QueryFactory>(factory: TFactory, ...input: InputArgs<TFactory>): QueryHandle<TFactory>;
|
|
148
|
+
export declare function waterfallHandle<TFactory extends QueryFactory>(factory: TFactory, handle: QueryHandle<TFactory>, update: (input: InputOf<TFactory>) => InputOf<TFactory>): QueryHandle<TFactory>;
|
|
149
|
+
//#endregion
|
package/dist/load.mjs
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { hashKey } from "./keys/keys.mjs";
|
|
2
|
+
import { optionsOf } from "./options.mjs";
|
|
3
|
+
import { entryOf, fetchEntry, isBrowserOnly, isInvalidated, isStale } from "./entry.mjs";
|
|
4
|
+
//#region src/load.ts
|
|
5
|
+
function loadEntry(kind, factory, args) {
|
|
6
|
+
return {
|
|
7
|
+
factory,
|
|
8
|
+
input: args[0],
|
|
9
|
+
kind,
|
|
10
|
+
pages: args[1]?.pages
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Start the query if the cache has no fresh data, and don't wait for it.
|
|
15
|
+
* It never makes the load reject: errors show up where a component reads
|
|
16
|
+
* the handle.
|
|
17
|
+
*
|
|
18
|
+
* @see https://raf-query.katt.dev/docs/starting-queries#prefetch-or-swr
|
|
19
|
+
*/
|
|
20
|
+
function prefetch(factory, ...args) {
|
|
21
|
+
return loadEntry("prefetch", factory, args);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Use cached data even when it's stale, and wait only when the cache has
|
|
25
|
+
* none. Stale data resolves at once and refetches in the background, as
|
|
26
|
+
* HTTP's
|
|
27
|
+
* [`stale-while-revalidate`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#stale-while-revalidate)
|
|
28
|
+
* does. The load rejects if the fetch it waits for fails.
|
|
29
|
+
*
|
|
30
|
+
* @see https://raf-query.katt.dev/docs/starting-queries#prefetch-or-swr
|
|
31
|
+
*/
|
|
32
|
+
function swr(factory, ...args) {
|
|
33
|
+
return loadEntry("swr", factory, args);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Wait for fresh data, as HTTP's
|
|
37
|
+
* [`must-revalidate`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#must-revalidate)
|
|
38
|
+
* does. Fresh cached data resolves at once without a refetch (`staleTime`
|
|
39
|
+
* is the max-age); with stale data or none it waits for the fetch. On a
|
|
40
|
+
* server client, data counts as fresh until a write invalidates it. The
|
|
41
|
+
* load rejects if the fetch fails.
|
|
42
|
+
*
|
|
43
|
+
* @see https://raf-query.katt.dev/docs/starting-queries#the-three-entries
|
|
44
|
+
*/
|
|
45
|
+
function revalidate(factory, ...args) {
|
|
46
|
+
return loadEntry("revalidate", factory, args);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* In place of a `load` entry: skip the query. Its handle is `undefined` and
|
|
50
|
+
* `data` has no key for it, so a component renders its reader only when
|
|
51
|
+
* there's a handle.
|
|
52
|
+
*
|
|
53
|
+
* ```ts
|
|
54
|
+
* const [handles] = await load(queryClient, {
|
|
55
|
+
* drafts: user.isAdmin ? prefetch(draftsQuery, { slug }) : skipToken,
|
|
56
|
+
* });
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @see https://raf-query.katt.dev/docs/starting-queries#conditional-queries
|
|
60
|
+
*/
|
|
61
|
+
const skipToken = Symbol("skipToken");
|
|
62
|
+
const loadRecords = /* @__PURE__ */ new WeakMap();
|
|
63
|
+
/** The latest `load` calls on a client, newest last. Recorded in development only. */
|
|
64
|
+
function loadsOf(client) {
|
|
65
|
+
return loadRecords.get(client) ?? [];
|
|
66
|
+
}
|
|
67
|
+
/** Read an entry's data the way its readers see it: through `select`. */
|
|
68
|
+
function readData(entry) {
|
|
69
|
+
const select = entry.options?.select;
|
|
70
|
+
return select ? select(entry.state.data) : entry.state.data;
|
|
71
|
+
}
|
|
72
|
+
/** Start the entry's request if its data isn't fresh. Never waits. */
|
|
73
|
+
function startIfStale(entry) {
|
|
74
|
+
if (isStale(entry) && !(entry.client.isServer && entry.state.hasData)) fetchEntry(entry);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Whether `revalidate` can use the entry's data. A server client belongs to
|
|
78
|
+
* one request, so what it fetched is fresh for that request until a write
|
|
79
|
+
* invalidates it.
|
|
80
|
+
*/
|
|
81
|
+
function isFresh(entry) {
|
|
82
|
+
return entry.client.isServer ? entry.state.hasData && !isInvalidated(entry) : !isStale(entry);
|
|
83
|
+
}
|
|
84
|
+
function waitFresh(entry, pages) {
|
|
85
|
+
if (isFresh(entry)) return Promise.resolve({ ok: true });
|
|
86
|
+
return fetchEntry(entry, { pages });
|
|
87
|
+
}
|
|
88
|
+
function waitAny(entry, pages) {
|
|
89
|
+
if (!entry.state.hasData) return waitFresh(entry, pages);
|
|
90
|
+
startIfStale(entry);
|
|
91
|
+
return Promise.resolve({ ok: true });
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Start a loader's queries and return a serializable handle for each. It
|
|
95
|
+
* starts every entry before it waits for any, so the order of the entries
|
|
96
|
+
* can't create a waterfall. Resolves with `[handles, data]` once every
|
|
97
|
+
* `swr` and `revalidate` entry has data, and rejects with the error as soon
|
|
98
|
+
* as one fails.
|
|
99
|
+
* `prefetch` entries never make it reject. A `skipToken` in place of an
|
|
100
|
+
* entry starts nothing and gets no handle.
|
|
101
|
+
*
|
|
102
|
+
* ```ts
|
|
103
|
+
* const [handles, data] = await load(queryClient, {
|
|
104
|
+
* comments: prefetch(commentsQuery, { slug }),
|
|
105
|
+
* post: swr(postQuery, { slug }),
|
|
106
|
+
* });
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* @see https://raf-query.katt.dev/docs/starting-queries
|
|
110
|
+
*/
|
|
111
|
+
async function load(client, entries) {
|
|
112
|
+
const started = Object.entries(entries).flatMap(([name, item]) => item === skipToken ? [] : [{
|
|
113
|
+
item,
|
|
114
|
+
name
|
|
115
|
+
}]).map((loaded) => {
|
|
116
|
+
const item = loaded.item;
|
|
117
|
+
const cached = entryOf(client, item.factory, item.input);
|
|
118
|
+
let wait;
|
|
119
|
+
if (item.kind === "prefetch") startIfStale(cached);
|
|
120
|
+
else if (isBrowserOnly(cached) && !cached.state.hasData) wait = Promise.resolve({
|
|
121
|
+
error: /* @__PURE__ */ new Error(`raf-query: ${cached.hash} has \`ssr: false\`, so the server can't wait for it. Load it with prefetch() instead of ${item.kind}().`),
|
|
122
|
+
ok: false
|
|
123
|
+
});
|
|
124
|
+
else wait = (item.kind === "revalidate" ? waitFresh : waitAny)(cached, item.pages);
|
|
125
|
+
return {
|
|
126
|
+
entry: cached,
|
|
127
|
+
item,
|
|
128
|
+
name: loaded.name,
|
|
129
|
+
wait
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
if (process.env.NODE_ENV !== "production") {
|
|
133
|
+
const records = loadRecords.get(client) ?? [];
|
|
134
|
+
records.push({
|
|
135
|
+
entries: started.map((one) => ({
|
|
136
|
+
hash: one.entry.hash,
|
|
137
|
+
kind: one.item.kind,
|
|
138
|
+
name: one.name
|
|
139
|
+
})),
|
|
140
|
+
startedAt: client.clock.now()
|
|
141
|
+
});
|
|
142
|
+
loadRecords.set(client, records.slice(-20));
|
|
143
|
+
}
|
|
144
|
+
const waits = started.map((one) => one.wait?.then((outcome) => {
|
|
145
|
+
if (!outcome.ok) throw outcome.error;
|
|
146
|
+
}));
|
|
147
|
+
await Promise.all(waits);
|
|
148
|
+
const handles = {};
|
|
149
|
+
const data = {};
|
|
150
|
+
for (const one of started) {
|
|
151
|
+
handles[one.name] = {
|
|
152
|
+
input: one.item.input,
|
|
153
|
+
queryKey: one.entry.key
|
|
154
|
+
};
|
|
155
|
+
if (one.wait) data[one.name] = readData(one.entry);
|
|
156
|
+
}
|
|
157
|
+
return [handles, data];
|
|
158
|
+
}
|
|
159
|
+
const waterfallHandles = /* @__PURE__ */ new WeakSet();
|
|
160
|
+
/** Whether a handle came from `waterfallHandle()`: reading it is expected to fetch. */
|
|
161
|
+
function isWaterfallHandle(handle) {
|
|
162
|
+
return waterfallHandles.has(handle);
|
|
163
|
+
}
|
|
164
|
+
function toHandle(factory, input) {
|
|
165
|
+
const handle = {
|
|
166
|
+
input,
|
|
167
|
+
queryKey: optionsOf(factory, input).queryKey
|
|
168
|
+
};
|
|
169
|
+
waterfallHandles.add(handle);
|
|
170
|
+
return handle;
|
|
171
|
+
}
|
|
172
|
+
function waterfallHandle(factory, ...args) {
|
|
173
|
+
if (args.length < 2) return toHandle(factory, args[0]);
|
|
174
|
+
const [handle, update] = args;
|
|
175
|
+
const next = toHandle(factory, update(handle.input));
|
|
176
|
+
return hashKey(next.queryKey) === hashKey(handle.queryKey) ? handle : next;
|
|
177
|
+
}
|
|
178
|
+
//#endregion
|
|
179
|
+
export { isWaterfallHandle, load, loadsOf, prefetch, readData, revalidate, skipToken, startIfStale, swr, waterfallHandle };
|