@raf-query/core 0.12.0 → 0.13.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/CHANGELOG.md +36 -2
- package/dist/client.d.mts +38 -5
- package/dist/client.mjs +37 -6
- package/dist/entry.d.mts +7 -0
- package/dist/entry.mjs +16 -2
- package/dist/features/focus-refetch/focus-refetch.d.mts +2 -0
- package/dist/features/focus-refetch/focus-refetch.mjs +2 -0
- package/dist/features/polling/polling.d.mts +5 -1
- package/dist/features/polling/polling.mjs +5 -1
- package/dist/features/reconnect-refetch/reconnect-refetch.d.mts +2 -0
- package/dist/features/reconnect-refetch/reconnect-refetch.mjs +2 -0
- package/dist/hydration/hydration.d.mts +38 -3
- package/dist/hydration/hydration.mjs +16 -2
- package/dist/index.d.mts +3 -2
- package/dist/index.mjs +2 -1
- package/dist/infinite/infinite.d.mts +37 -15
- package/dist/infinite/infinite.mjs +41 -8
- package/dist/infinite/paging.d.mts +71 -0
- package/dist/infinite/paging.mjs +62 -0
- package/dist/internal.d.mts +3 -3
- package/dist/internal.mjs +3 -3
- package/dist/keys/keys.d.mts +9 -1
- package/dist/keys/targets.d.mts +8 -2
- package/dist/links/retry/retry.d.mts +7 -0
- package/dist/links/retry/retry.mjs +2 -0
- package/dist/links/timeout/timeout.d.mts +10 -2
- package/dist/links/timeout/timeout.mjs +10 -2
- package/dist/load.d.mts +28 -3
- package/dist/load.mjs +26 -3
- package/dist/options.d.mts +79 -9
- package/dist/options.mjs +7 -3
- package/dist/presets.d.mts +7 -1
- package/dist/presets.mjs +2 -0
- package/dist/root.d.mts +5 -1
- package/dist/thenable.d.mts +2 -0
- package/dist/verbs.d.mts +56 -15
- package/dist/verbs.mjs +34 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,14 +1,48 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.13.1](https://github.com/KATT/raf-query/compare/0.13.0...0.13.1) (2026-11-10)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* **core:** keepPages, for lists whose start stays out of the key ([#248](https://github.com/KATT/raf-query/issues/248)) ([164c88c](https://github.com/KATT/raf-query/commit/164c88c4509a34c9ec51f089c3b70c03ea13cac0))
|
|
8
|
+
|
|
9
|
+
## [0.13.0](https://github.com/KATT/raf-query/compare/0.12.0...0.13.0) (2026-11-10)
|
|
10
|
+
|
|
11
|
+
### ⚠ BREAKING CHANGES
|
|
12
|
+
|
|
13
|
+
- **core:** paging lives in core; useInfiniteQuery reads core's PageControls ([#246](https://github.com/KATT/raf-query/issues/246))
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
- **core:** paging lives in core; useInfiniteQuery reads core's PageControls ([#246](https://github.com/KATT/raf-query/issues/246)) ([f6b4ed2](https://github.com/KATT/raf-query/commit/f6b4ed210340b4b25bf3316ef08a9c8ceb9ed112))
|
|
18
|
+
- **core:** pass the client making the request to queryFn ([#241](https://github.com/KATT/raf-query/issues/241)) ([8c85746](https://github.com/KATT/raf-query/commit/8c85746c230bc3d8a426b32a130a260fa7e8ca62))
|
|
19
|
+
- **core:** replay cached entries to a new client subscriber ([#243](https://github.com/KATT/raf-query/issues/243)) ([1455eed](https://github.com/KATT/raf-query/commit/1455eed2612fe69f0f10bfec08cfd552ef90c786))
|
|
20
|
+
- **core:** ssr: false for queries only a browser can run ([#240](https://github.com/KATT/raf-query/issues/240)) ([077de62](https://github.com/KATT/raf-query/commit/077de6223a92b8bd8d35f7df043d1efe147ca403))
|
|
21
|
+
|
|
22
|
+
### Bug Fixes
|
|
23
|
+
|
|
24
|
+
- **core:** infer factories built inline by a generic maker in setData ([#244](https://github.com/KATT/raf-query/issues/244)) ([da87c07](https://github.com/KATT/raf-query/commit/da87c07a3463a919c154ac3ac5fba3d546b3231e))
|
|
25
|
+
- **core:** keep data written while a request ran ([#239](https://github.com/KATT/raf-query/issues/239)) ([4cb7cc0](https://github.com/KATT/raf-query/commit/4cb7cc0605a2d4637591eb365153c5e955eb41a8))
|
|
26
|
+
- **core:** start features once for providers that share a client ([#242](https://github.com/KATT/raf-query/issues/242)) ([d5968fb](https://github.com/KATT/raf-query/commit/d5968fb140429a1b2e7fb94662c266a52e877cc0))
|
|
27
|
+
|
|
28
|
+
### Documentation
|
|
29
|
+
|
|
30
|
+
- every example is the blog's posts, comments and authors ([#236](https://github.com/KATT/raf-query/issues/236)) ([2551e97](https://github.com/KATT/raf-query/commit/2551e9710aa7b149be333a1675dae31d9d1f5efd)), references [#230](https://github.com/KATT/raf-query/issues/230)
|
|
31
|
+
|
|
32
|
+
### Miscellaneous Chores
|
|
33
|
+
|
|
34
|
+
- **lint:** require a docs link on every public export ([#237](https://github.com/KATT/raf-query/issues/237)) ([b5c8133](https://github.com/KATT/raf-query/commit/b5c8133c129e0412e82cd2f24da6a2516b4a2012))
|
|
35
|
+
- unblock CI: [@see](https://github.com/see) links and the RSC test's build ([#245](https://github.com/KATT/raf-query/issues/245)) ([84927e4](https://github.com/KATT/raf-query/commit/84927e4a900f7608e1e17b022e28afadbe00e4ae)), references [#243](https://github.com/KATT/raf-query/issues/243) [#246](https://github.com/KATT/raf-query/issues/246) [#240](https://github.com/KATT/raf-query/issues/240) [#238](https://github.com/KATT/raf-query/issues/238)
|
|
36
|
+
|
|
3
37
|
## [0.12.0](https://github.com/KATT/raf-query/compare/0.11.1...0.12.0) (2026-11-08)
|
|
4
38
|
|
|
5
39
|
### ⚠ BREAKING CHANGES
|
|
6
40
|
|
|
7
|
-
|
|
41
|
+
- greenfield rewrite on a promise kernel, with load() handles and opt-in behaviors ([#230](https://github.com/KATT/raf-query/issues/230))
|
|
8
42
|
|
|
9
43
|
### Features
|
|
10
44
|
|
|
11
|
-
|
|
45
|
+
- greenfield rewrite on a promise kernel, with load() handles and opt-in behaviors ([#230](https://github.com/KATT/raf-query/issues/230)) ([e2a6f85](https://github.com/KATT/raf-query/commit/e2a6f85297992dc8a5cdd3f871a54452393ae978))
|
|
12
46
|
|
|
13
47
|
## [0.11.1](https://github.com/KATT/raf-query/compare/0.11.0...0.11.1) (2026-10-17)
|
|
14
48
|
|
package/dist/client.d.mts
CHANGED
|
@@ -11,14 +11,22 @@ type FeatureFunction = (client: QueryClient, signal: AbortSignal) => void;
|
|
|
11
11
|
export type AnyLink = LinkFunction & AnyPart;
|
|
12
12
|
/** Any feature, whatever `meta` it reads. */
|
|
13
13
|
export type AnyFeature = FeatureFunction & AnyPart;
|
|
14
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Time and timers, injectable so tests control them without patching globals.
|
|
16
|
+
*
|
|
17
|
+
* @see https://raf-query.katt.dev/docs/testing#time
|
|
18
|
+
*/
|
|
15
19
|
export interface Clock {
|
|
16
20
|
clearTimeout(handle: unknown): void;
|
|
17
21
|
now(): number;
|
|
18
22
|
setTimeout(callback: () => void, ms: number): unknown;
|
|
19
23
|
}
|
|
20
24
|
export declare const systemClock: Clock;
|
|
21
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* One request, as links see it. `TMeta` is what the link declares.
|
|
27
|
+
*
|
|
28
|
+
* @see https://raf-query.katt.dev/docs/links-and-features#links-and-features
|
|
29
|
+
*/
|
|
22
30
|
export interface Operation<TMeta extends object = object> {
|
|
23
31
|
readonly client: QueryClient;
|
|
24
32
|
/** The entry's data when the request started (paged queries extend it). */
|
|
@@ -40,11 +48,15 @@ export interface Operation<TMeta extends object = object> {
|
|
|
40
48
|
* Wraps every request, like a tRPC link. Call `next(op)` to run the rest of
|
|
41
49
|
* the chain; the last link is the query's own `queryFn`. `TDecl` is the
|
|
42
50
|
* `meta` it reads: see {@link link}.
|
|
51
|
+
*
|
|
52
|
+
* @see https://raf-query.katt.dev/docs/links-and-features#links-and-features
|
|
43
53
|
*/
|
|
44
54
|
export type Link<TDecl extends Decl = Decl> = LinkFunction & Declares<TDecl>;
|
|
45
55
|
/**
|
|
46
56
|
* A cache-wide behavior, started when a provider mounts the client and
|
|
47
57
|
* stopped by `signal`. `TDecl` is the `meta` it reads: see {@link feature}.
|
|
58
|
+
*
|
|
59
|
+
* @see https://raf-query.katt.dev/docs/links-and-features#links-and-features
|
|
48
60
|
*/
|
|
49
61
|
export type Feature<TDecl extends Decl = Decl> = FeatureFunction & Declares<TDecl>;
|
|
50
62
|
/**
|
|
@@ -56,6 +68,8 @@ export type Feature<TDecl extends Decl = Decl> = FeatureFunction & Declares<TDec
|
|
|
56
68
|
* withTrace(op.meta.traceId, () => next(op)),
|
|
57
69
|
* );
|
|
58
70
|
* ```
|
|
71
|
+
*
|
|
72
|
+
* @see https://raf-query.katt.dev/docs/links-and-features#links-and-features
|
|
59
73
|
*/
|
|
60
74
|
export declare function link<TDecl extends Decl = Decl>(run: (op: Operation<MetaOfDecl<TDecl> & object>, next: (op: Operation) => Promise<unknown>) => Promise<unknown>): Link<TDecl>;
|
|
61
75
|
/**
|
|
@@ -66,6 +80,8 @@ export declare function link<TDecl extends Decl = Decl>(run: (op: Operation<Meta
|
|
|
66
80
|
* ```ts
|
|
67
81
|
* const ownership = feature<{ meta: { owner?: "posts-team" | "users-team" } }>();
|
|
68
82
|
* ```
|
|
83
|
+
*
|
|
84
|
+
* @see https://raf-query.katt.dev/docs/links-and-features#links-and-features
|
|
69
85
|
*/
|
|
70
86
|
export declare function feature<TDecl extends Decl = Decl>(setup?: FeatureFunction): Feature<TDecl>;
|
|
71
87
|
export type ClientEvent = {
|
|
@@ -75,6 +91,11 @@ export type ClientEvent = {
|
|
|
75
91
|
readonly entry: Entry;
|
|
76
92
|
readonly type: "readers";
|
|
77
93
|
};
|
|
94
|
+
/**
|
|
95
|
+
* What `createQueryClient` takes: links, features and the cache-wide defaults.
|
|
96
|
+
*
|
|
97
|
+
* @see https://raf-query.katt.dev/docs/important-defaults#changing-the-defaults
|
|
98
|
+
*/
|
|
78
99
|
export interface QueryClientConfig {
|
|
79
100
|
readonly clock?: Clock;
|
|
80
101
|
/** Behaviors started while a provider has the client mounted. */
|
|
@@ -94,6 +115,8 @@ export interface QueryClientConfig {
|
|
|
94
115
|
* A query cache. `TTypes` is its root's types, which factories built with
|
|
95
116
|
* `bindQueryOptions<typeof makeQueryClient>()` are checked against. The bare
|
|
96
117
|
* `QueryClient` type takes a client of any root.
|
|
118
|
+
*
|
|
119
|
+
* @see https://raf-query.katt.dev/docs/api-reference#the-client
|
|
97
120
|
*/
|
|
98
121
|
export interface QueryClient<TTypes extends RootTypes = AnyRoot> {
|
|
99
122
|
/** Entries changed since the last notification. */
|
|
@@ -111,8 +134,15 @@ export interface QueryClient<TTypes extends RootTypes = AnyRoot> {
|
|
|
111
134
|
readonly clock: Clock;
|
|
112
135
|
readonly config: QueryClientConfig;
|
|
113
136
|
readonly isServer: boolean;
|
|
114
|
-
/**
|
|
115
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Cache events: entries added, updated, removed, or gaining and losing
|
|
139
|
+
* readers. With `replay: true`, the listener first gets an `added` event
|
|
140
|
+
* for every entry the cache already holds, so a feature that keeps
|
|
141
|
+
* entries in sync starts from what's there.
|
|
142
|
+
*/
|
|
143
|
+
subscribe(listener: (event: ClientEvent) => void, options?: SubscribeOptions & {
|
|
144
|
+
readonly replay?: boolean;
|
|
145
|
+
}): () => void;
|
|
116
146
|
}
|
|
117
147
|
/**
|
|
118
148
|
* Create a query client. Behaviors are opt-in: pass `links` and `features`,
|
|
@@ -126,6 +156,8 @@ export interface QueryClient<TTypes extends RootTypes = AnyRoot> {
|
|
|
126
156
|
*
|
|
127
157
|
* Make one per request on the server (in a loader or a request-scoped
|
|
128
158
|
* cache), never at module level.
|
|
159
|
+
*
|
|
160
|
+
* @see https://raf-query.katt.dev/docs/important-defaults
|
|
129
161
|
*/
|
|
130
162
|
export declare function createQueryClient<const TLinks extends ReadonlyArray<AnyLink> = [], const TFeatures extends ReadonlyArray<AnyFeature> = []>(config?: QueryClientConfig & {
|
|
131
163
|
readonly features?: TFeatures;
|
|
@@ -135,7 +167,8 @@ export declare function createQueryClient<const TLinks extends ReadonlyArray<Any
|
|
|
135
167
|
}>;
|
|
136
168
|
/**
|
|
137
169
|
* Start the client's features. Providers call it while mounted; the
|
|
138
|
-
* returned function stops them.
|
|
170
|
+
* returned function stops them. Mounts are counted, so features start once
|
|
171
|
+
* however many providers share the client, and stop with the last.
|
|
139
172
|
*/
|
|
140
173
|
export declare function mount(client: QueryClient): () => void;
|
|
141
174
|
//#endregion
|
package/dist/client.mjs
CHANGED
|
@@ -16,6 +16,8 @@ const systemClock = {
|
|
|
16
16
|
* withTrace(op.meta.traceId, () => next(op)),
|
|
17
17
|
* );
|
|
18
18
|
* ```
|
|
19
|
+
*
|
|
20
|
+
* @see https://raf-query.katt.dev/docs/links-and-features#links-and-features
|
|
19
21
|
*/
|
|
20
22
|
function link(run) {
|
|
21
23
|
return run;
|
|
@@ -29,6 +31,8 @@ const noop = () => {};
|
|
|
29
31
|
* ```ts
|
|
30
32
|
* const ownership = feature<{ meta: { owner?: "posts-team" | "users-team" } }>();
|
|
31
33
|
* ```
|
|
34
|
+
*
|
|
35
|
+
* @see https://raf-query.katt.dev/docs/links-and-features#links-and-features
|
|
32
36
|
*/
|
|
33
37
|
function feature(setup = noop) {
|
|
34
38
|
return setup;
|
|
@@ -45,29 +49,56 @@ function feature(setup = noop) {
|
|
|
45
49
|
*
|
|
46
50
|
* Make one per request on the server (in a loader or a request-scoped
|
|
47
51
|
* cache), never at module level.
|
|
52
|
+
*
|
|
53
|
+
* @see https://raf-query.katt.dev/docs/important-defaults
|
|
48
54
|
*/
|
|
49
55
|
function createQueryClient(config = {}) {
|
|
50
56
|
const events = listeners();
|
|
57
|
+
const entries = /* @__PURE__ */ new Map();
|
|
51
58
|
return {
|
|
52
59
|
"~changed": /* @__PURE__ */ new Set(),
|
|
53
|
-
"~entries":
|
|
60
|
+
"~entries": entries,
|
|
54
61
|
"~events": events,
|
|
55
62
|
"~seq": 0,
|
|
56
63
|
"~stamps": [],
|
|
57
64
|
clock: config.clock ?? systemClock,
|
|
58
65
|
config,
|
|
59
66
|
isServer: config.isServer ?? !("window" in globalThis),
|
|
60
|
-
subscribe: (listener, options) =>
|
|
67
|
+
subscribe: (listener, options) => {
|
|
68
|
+
const unsubscribe = events.subscribe(listener, options);
|
|
69
|
+
if (options?.replay && !options.signal?.aborted) for (const entry of entries.values()) listener({
|
|
70
|
+
entry,
|
|
71
|
+
type: "added"
|
|
72
|
+
});
|
|
73
|
+
return unsubscribe;
|
|
74
|
+
}
|
|
61
75
|
};
|
|
62
76
|
}
|
|
77
|
+
const mounted = /* @__PURE__ */ new WeakMap();
|
|
63
78
|
/**
|
|
64
79
|
* Start the client's features. Providers call it while mounted; the
|
|
65
|
-
* returned function stops them.
|
|
80
|
+
* returned function stops them. Mounts are counted, so features start once
|
|
81
|
+
* however many providers share the client, and stop with the last.
|
|
66
82
|
*/
|
|
67
83
|
function mount(client) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
84
|
+
let current = mounted.get(client);
|
|
85
|
+
if (!current) {
|
|
86
|
+
current = {
|
|
87
|
+
controller: new AbortController(),
|
|
88
|
+
count: 0
|
|
89
|
+
};
|
|
90
|
+
mounted.set(client, current);
|
|
91
|
+
for (const start of client.config.features ?? []) start(client, current.controller.signal);
|
|
92
|
+
}
|
|
93
|
+
const shared = current;
|
|
94
|
+
shared.count += 1;
|
|
95
|
+
return () => {
|
|
96
|
+
shared.count -= 1;
|
|
97
|
+
if (shared.count === 0) {
|
|
98
|
+
mounted.delete(client);
|
|
99
|
+
shared.controller.abort();
|
|
100
|
+
}
|
|
101
|
+
};
|
|
71
102
|
}
|
|
72
103
|
//#endregion
|
|
73
104
|
export { createQueryClient, feature, link, mount, systemClock };
|
package/dist/entry.d.mts
CHANGED
|
@@ -46,6 +46,11 @@ export interface Entry {
|
|
|
46
46
|
state: EntryState;
|
|
47
47
|
thenable: Thenable<unknown>;
|
|
48
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Make the `AbortError` (a `DOMException`) that a `load` waiting on a removed query rejects with.
|
|
51
|
+
*
|
|
52
|
+
* @see https://raf-query.katt.dev/docs/query-cancellation#when-requests-are-aborted
|
|
53
|
+
*/
|
|
49
54
|
export declare function abortError(): DOMException;
|
|
50
55
|
/**
|
|
51
56
|
* The entry for a factory's input, created if missing, with the factory's
|
|
@@ -55,6 +60,8 @@ export declare function abortError(): DOMException;
|
|
|
55
60
|
export declare function entryOf(client: QueryClient, factory: AnyFactory, input: unknown): Entry;
|
|
56
61
|
/** Whether an invalidation newer than the entry's data covers it. */
|
|
57
62
|
export declare function isInvalidated(entry: Entry): boolean;
|
|
63
|
+
/** Whether the entry is a browser-only query (`ssr: false`) on a server client: nothing starts it there. */
|
|
64
|
+
export declare function isBrowserOnly(entry: Entry): boolean;
|
|
58
65
|
/** Whether the entry's data should be refetched before it's trusted. */
|
|
59
66
|
export declare function isStale(entry: Entry): boolean;
|
|
60
67
|
export interface FetchRequest {
|
package/dist/entry.mjs
CHANGED
|
@@ -16,6 +16,11 @@ const initialState = {
|
|
|
16
16
|
updatedAt: 0
|
|
17
17
|
};
|
|
18
18
|
const fiveMinutes = 3e5;
|
|
19
|
+
/**
|
|
20
|
+
* Make the `AbortError` (a `DOMException`) that a `load` waiting on a removed query rejects with.
|
|
21
|
+
*
|
|
22
|
+
* @see https://raf-query.katt.dev/docs/query-cancellation#when-requests-are-aborted
|
|
23
|
+
*/
|
|
19
24
|
function abortError() {
|
|
20
25
|
return new DOMException("The query was cancelled", "AbortError");
|
|
21
26
|
}
|
|
@@ -123,6 +128,10 @@ function entryOf(client, factory, input) {
|
|
|
123
128
|
function isInvalidated(entry) {
|
|
124
129
|
return entry.client["~stamps"].some((stamp) => stamp.at > entry.requestedAt && matches(entry, stamp));
|
|
125
130
|
}
|
|
131
|
+
/** Whether the entry is a browser-only query (`ssr: false`) on a server client: nothing starts it there. */
|
|
132
|
+
function isBrowserOnly(entry) {
|
|
133
|
+
return entry.client.isServer && entry.options?.ssr === false;
|
|
134
|
+
}
|
|
126
135
|
/** Whether the entry's data should be refetched before it's trusted. */
|
|
127
136
|
function isStale(entry) {
|
|
128
137
|
const state = entry.state;
|
|
@@ -206,6 +215,7 @@ function terminal(op) {
|
|
|
206
215
|
const options = op.options;
|
|
207
216
|
const paged = options["~run"];
|
|
208
217
|
resolve(paged ? paged(op) : options.queryFn({
|
|
218
|
+
client: op.client,
|
|
209
219
|
meta: op.meta,
|
|
210
220
|
queryKey: op.queryKey,
|
|
211
221
|
signal: op.signal
|
|
@@ -229,7 +239,7 @@ function fetchEntry(entry, request = {}) {
|
|
|
229
239
|
const current = entry.run;
|
|
230
240
|
if (current && !request.restart && request.direction === void 0) return current.done.promise;
|
|
231
241
|
const options = entry.options;
|
|
232
|
-
if (!options) return Promise.resolve({ ok: true });
|
|
242
|
+
if (!options || isBrowserOnly(entry)) return Promise.resolve({ ok: true });
|
|
233
243
|
current?.controller.abort();
|
|
234
244
|
const client = entry.client;
|
|
235
245
|
const run = {
|
|
@@ -263,6 +273,10 @@ function fetchEntry(entry, request = {}) {
|
|
|
263
273
|
pump(entry, run, result, options.stream);
|
|
264
274
|
return;
|
|
265
275
|
}
|
|
276
|
+
if (!options["~run"] && entry.requestedAt > run.startedAt) {
|
|
277
|
+
finish(entry, run, { ok: true });
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
266
280
|
write(entry, result, client.clock.now(), run.startedAt);
|
|
267
281
|
finish(entry, run, { ok: true });
|
|
268
282
|
}, (error) => {
|
|
@@ -352,4 +366,4 @@ function invalidate(client, makeStamps) {
|
|
|
352
366
|
return Promise.all(refetches).then(() => {});
|
|
353
367
|
}
|
|
354
368
|
//#endregion
|
|
355
|
-
export { abortError, adopt, entryForKey, entryOf, fetchEntry, invalidate, isInvalidated, isStale, remove, reset, subscribeEntry, write };
|
|
369
|
+
export { abortError, adopt, entryForKey, entryOf, fetchEntry, invalidate, isBrowserOnly, isInvalidated, isStale, remove, reset, subscribeEntry, write };
|
|
@@ -8,6 +8,8 @@ export interface FocusRefetchMeta {
|
|
|
8
8
|
/**
|
|
9
9
|
* Refetch read, stale queries when the window regains focus, except those
|
|
10
10
|
* with `meta: { refetchOnWindowFocus: false }`.
|
|
11
|
+
*
|
|
12
|
+
* @see https://raf-query.katt.dev/docs/window-focus-refetching
|
|
11
13
|
*/
|
|
12
14
|
export declare function focusRefetch(): Feature<{
|
|
13
15
|
readonly meta: FocusRefetchMeta;
|
|
@@ -4,6 +4,8 @@ import { refetchStaleReads } from "../shared.mjs";
|
|
|
4
4
|
/**
|
|
5
5
|
* Refetch read, stale queries when the window regains focus, except those
|
|
6
6
|
* with `meta: { refetchOnWindowFocus: false }`.
|
|
7
|
+
*
|
|
8
|
+
* @see https://raf-query.katt.dev/docs/window-focus-refetching
|
|
7
9
|
*/
|
|
8
10
|
function focusRefetch() {
|
|
9
11
|
return feature((client, signal) => {
|
|
@@ -5,7 +5,11 @@ export interface PollingMeta {
|
|
|
5
5
|
/** Refetch every `n` ms while the query is read. */
|
|
6
6
|
readonly refetchInterval?: number | false;
|
|
7
7
|
}
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* Refetch read queries every `meta.refetchInterval` ms.
|
|
10
|
+
*
|
|
11
|
+
* @see https://raf-query.katt.dev/docs/polling
|
|
12
|
+
*/
|
|
9
13
|
export declare function polling(): Feature<{
|
|
10
14
|
readonly meta: PollingMeta;
|
|
11
15
|
}>;
|
|
@@ -3,7 +3,11 @@ import { isNumber } from "../../guards.mjs";
|
|
|
3
3
|
import { fetchEntry } from "../../entry.mjs";
|
|
4
4
|
import { metaOf } from "../shared.mjs";
|
|
5
5
|
//#region src/features/polling/polling.ts
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* Refetch read queries every `meta.refetchInterval` ms.
|
|
8
|
+
*
|
|
9
|
+
* @see https://raf-query.katt.dev/docs/polling
|
|
10
|
+
*/
|
|
7
11
|
function polling() {
|
|
8
12
|
return feature((client, signal) => {
|
|
9
13
|
const timers = /* @__PURE__ */ new Map();
|
|
@@ -8,6 +8,8 @@ export interface ReconnectRefetchMeta {
|
|
|
8
8
|
/**
|
|
9
9
|
* Refetch read, stale queries when the browser comes back online, except
|
|
10
10
|
* those with `meta: { refetchOnReconnect: false }`.
|
|
11
|
+
*
|
|
12
|
+
* @see https://raf-query.katt.dev/docs/testing#focus-and-the-network
|
|
11
13
|
*/
|
|
12
14
|
export declare function reconnectRefetch(): Feature<{
|
|
13
15
|
readonly meta: ReconnectRefetchMeta;
|
|
@@ -4,6 +4,8 @@ import { refetchStaleReads } from "../shared.mjs";
|
|
|
4
4
|
/**
|
|
5
5
|
* Refetch read, stale queries when the browser comes back online, except
|
|
6
6
|
* those with `meta: { refetchOnReconnect: false }`.
|
|
7
|
+
*
|
|
8
|
+
* @see https://raf-query.katt.dev/docs/testing#focus-and-the-network
|
|
7
9
|
*/
|
|
8
10
|
function reconnectRefetch() {
|
|
9
11
|
return feature((client, signal) => {
|
|
@@ -2,7 +2,11 @@ import { QueryKey } from "../keys/keys.mjs";
|
|
|
2
2
|
import { Entry } from "../entry.mjs";
|
|
3
3
|
import { QueryClient } from "../client.mjs";
|
|
4
4
|
//#region src/hydration/hydration.d.ts
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* What a dehydrated pending entry's promise resolves to.
|
|
7
|
+
*
|
|
8
|
+
* @see https://raf-query.katt.dev/docs/ssr-and-hydration
|
|
9
|
+
*/
|
|
6
10
|
export interface DehydratedResult {
|
|
7
11
|
readonly data?: unknown;
|
|
8
12
|
/** When the sender got the result (ms since epoch). */
|
|
@@ -12,6 +16,8 @@ export interface DehydratedResult {
|
|
|
12
16
|
* One cache entry in transit. Settled entries carry `data` and
|
|
13
17
|
* `updatedAt > 0`; entries still loading carry their request's `promise`,
|
|
14
18
|
* so the receiver resumes it instead of fetching again.
|
|
19
|
+
*
|
|
20
|
+
* @see https://raf-query.katt.dev/docs/ssr-and-hydration
|
|
15
21
|
*/
|
|
16
22
|
export interface DehydratedEntry {
|
|
17
23
|
readonly data?: unknown;
|
|
@@ -20,9 +26,19 @@ export interface DehydratedEntry {
|
|
|
20
26
|
/** When the data was fetched; `0` while pending. */
|
|
21
27
|
readonly updatedAt: number;
|
|
22
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* A cache, serialized by {@link dehydrate} for {@link hydrate}.
|
|
31
|
+
*
|
|
32
|
+
* @see https://raf-query.katt.dev/docs/ssr-and-hydration
|
|
33
|
+
*/
|
|
23
34
|
export interface DehydratedState {
|
|
24
35
|
readonly entries: ReadonlyArray<DehydratedEntry>;
|
|
25
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Options for {@link dehydrate} and {@link dehydrateStream}.
|
|
39
|
+
*
|
|
40
|
+
* @see https://raf-query.katt.dev/docs/ssr-and-hydration
|
|
41
|
+
*/
|
|
26
42
|
export interface DehydrateOptions {
|
|
27
43
|
/**
|
|
28
44
|
* Which entries to send. Default: entries with data or a request in
|
|
@@ -40,16 +56,31 @@ export interface DehydrateOptions {
|
|
|
40
56
|
/**
|
|
41
57
|
* What a streamed pending entry rejects with when its server request threw:
|
|
42
58
|
* the browser learns which query failed, not why.
|
|
59
|
+
*
|
|
60
|
+
* @see https://raf-query.katt.dev/docs/ssr-and-hydration#errors
|
|
43
61
|
*/
|
|
44
62
|
export declare class RedactedError extends Error {
|
|
45
63
|
readonly name = "RedactedError";
|
|
46
64
|
readonly hash: string;
|
|
47
65
|
constructor(hash: string);
|
|
48
66
|
}
|
|
49
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* The default filter: entries with data or a request in flight.
|
|
69
|
+
*
|
|
70
|
+
* @see https://raf-query.katt.dev/docs/ssr-and-hydration
|
|
71
|
+
*/
|
|
50
72
|
export declare function canDehydrate(entry: Entry): boolean;
|
|
51
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* Snapshot the client's entries for transfer.
|
|
75
|
+
*
|
|
76
|
+
* @see https://raf-query.katt.dev/docs/ssr-and-hydration
|
|
77
|
+
*/
|
|
52
78
|
export declare function dehydrate(client: QueryClient, options?: DehydrateOptions): DehydratedState;
|
|
79
|
+
/**
|
|
80
|
+
* What {@link dehydrateStream} returns: the entries to send first, then their updates.
|
|
81
|
+
*
|
|
82
|
+
* @see https://raf-query.katt.dev/docs/ssr-and-hydration
|
|
83
|
+
*/
|
|
53
84
|
export interface DehydratedStream {
|
|
54
85
|
/** Stop: send what changed, then end `updates`. */
|
|
55
86
|
close(): void;
|
|
@@ -61,6 +92,8 @@ export interface DehydratedStream {
|
|
|
61
92
|
/**
|
|
62
93
|
* The cache now, then entries as they start, until `close()`. Snapshots and
|
|
63
94
|
* subscribes in one synchronous step, so no change falls between the two.
|
|
95
|
+
*
|
|
96
|
+
* @see https://raf-query.katt.dev/docs/ssr-and-hydration
|
|
64
97
|
*/
|
|
65
98
|
export declare function dehydrateStream(client: QueryClient, options?: DehydrateOptions): DehydratedStream;
|
|
66
99
|
/**
|
|
@@ -68,6 +101,8 @@ export declare function dehydrateStream(client: QueryClient, options?: Dehydrate
|
|
|
68
101
|
* data. A pending entry the client has nothing for resumes the sender's
|
|
69
102
|
* request; one that has data or a request of its own waits for the
|
|
70
103
|
* sender's, takes it if newer, and revalidates if the sender's failed.
|
|
104
|
+
*
|
|
105
|
+
* @see https://raf-query.katt.dev/docs/ssr-and-hydration
|
|
71
106
|
*/
|
|
72
107
|
export declare function hydrate(client: QueryClient, state: DehydratedState): void;
|
|
73
108
|
//#endregion
|
|
@@ -3,6 +3,8 @@ import { adopt, entryForKey, fetchEntry, isStale, write } from "../entry.mjs";
|
|
|
3
3
|
/**
|
|
4
4
|
* What a streamed pending entry rejects with when its server request threw:
|
|
5
5
|
* the browser learns which query failed, not why.
|
|
6
|
+
*
|
|
7
|
+
* @see https://raf-query.katt.dev/docs/ssr-and-hydration#errors
|
|
6
8
|
*/
|
|
7
9
|
var RedactedError = class extends Error {
|
|
8
10
|
name = "RedactedError";
|
|
@@ -12,7 +14,11 @@ var RedactedError = class extends Error {
|
|
|
12
14
|
this.hash = hash;
|
|
13
15
|
}
|
|
14
16
|
};
|
|
15
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* The default filter: entries with data or a request in flight.
|
|
19
|
+
*
|
|
20
|
+
* @see https://raf-query.katt.dev/docs/ssr-and-hydration
|
|
21
|
+
*/
|
|
16
22
|
function canDehydrate(entry) {
|
|
17
23
|
const state = entry.state;
|
|
18
24
|
return state.hasData || state.isFetching;
|
|
@@ -54,13 +60,19 @@ function dehydrateEntries(entries, options) {
|
|
|
54
60
|
}
|
|
55
61
|
return { entries: dehydrated };
|
|
56
62
|
}
|
|
57
|
-
/**
|
|
63
|
+
/**
|
|
64
|
+
* Snapshot the client's entries for transfer.
|
|
65
|
+
*
|
|
66
|
+
* @see https://raf-query.katt.dev/docs/ssr-and-hydration
|
|
67
|
+
*/
|
|
58
68
|
function dehydrate(client, options = {}) {
|
|
59
69
|
return dehydrateEntries(client["~entries"].values(), options);
|
|
60
70
|
}
|
|
61
71
|
/**
|
|
62
72
|
* The cache now, then entries as they start, until `close()`. Snapshots and
|
|
63
73
|
* subscribes in one synchronous step, so no change falls between the two.
|
|
74
|
+
*
|
|
75
|
+
* @see https://raf-query.katt.dev/docs/ssr-and-hydration
|
|
64
76
|
*/
|
|
65
77
|
function dehydrateStream(client, options = {}) {
|
|
66
78
|
const send = {
|
|
@@ -112,6 +124,8 @@ function takeNewer(entry, result) {
|
|
|
112
124
|
* data. A pending entry the client has nothing for resumes the sender's
|
|
113
125
|
* request; one that has data or a request of its own waits for the
|
|
114
126
|
* sender's, takes it if newer, and revalidates if the sender's failed.
|
|
127
|
+
*
|
|
128
|
+
* @see https://raf-query.katt.dev/docs/ssr-and-hydration
|
|
115
129
|
*/
|
|
116
130
|
function hydrate(client, state) {
|
|
117
131
|
for (const sent of state.entries) {
|
package/dist/index.d.mts
CHANGED
|
@@ -10,9 +10,10 @@ import { reconnectRefetch } from "./features/reconnect-refetch/reconnect-refetch
|
|
|
10
10
|
import { polling } from "./features/polling/polling.mjs";
|
|
11
11
|
import { DehydrateOptions, DehydratedEntry, DehydratedResult, DehydratedState, DehydratedStream, RedactedError, canDehydrate, dehydrate, dehydrateStream, hydrate } from "./hydration/hydration.mjs";
|
|
12
12
|
import { InfiniteData, InfiniteQueryFunctionContext, InfiniteQueryOptions, InfiniteQueryOptionsBuilder, bindInfiniteQueryOptions, infiniteQueryOptions } from "./infinite/infinite.mjs";
|
|
13
|
+
import { ClientFor, PartialInput, getData, invalidateAll, invalidateMany, invalidateOne, isFetching, removeAll, removeMany, removeOne, resetAll, resetMany, resetOne, setData } from "./verbs.mjs";
|
|
14
|
+
import { PageControls, PageDirection, PageState, fetchNextPage, fetchPreviousPage, hasNextPage, hasPreviousPage } from "./infinite/paging.mjs";
|
|
13
15
|
import { RetryOptions, retry } from "./links/retry/retry.mjs";
|
|
14
16
|
import { QueryTimeoutError, timeout } from "./links/timeout/timeout.mjs";
|
|
15
17
|
import { LoadEntry, LoadEntryOptions, Loaded, QueryHandle, load, prefetch, revalidate, skipToken, swr, waterfallHandle } from "./load.mjs";
|
|
16
18
|
import { Recommended, recommended } from "./presets.mjs";
|
|
17
|
-
|
|
18
|
-
export { type ClientFor, type Clock, type DataOf, type DehydrateOptions, type DehydratedEntry, type DehydratedResult, type DehydratedState, type DehydratedStream, type Feature, type Group, type InfiniteData, type InfiniteQueryFactory, type InfiniteQueryFunctionContext, type InfiniteQueryOptions, type InfiniteQueryOptionsBuilder, type InputOf, type Link, type LoadEntry, type LoadEntryOptions, type Loaded, type Operation, type PartialInput, type QueryClient, type QueryClientConfig, type QueryFactory, type QueryFunctionContext, type QueryHandle, type QueryInfo, type QueryKey, type QueryMeta, type QueryOptions, type QueryOptionsBuilder, QueryTimeoutError, type Recommended, RedactedError, type RetryOptions, type SingleQueryFactory, type StreamOptions, type Target, type Thenable, abortError, bindInfiniteQueryOptions, bindQueryOptions, canDehydrate, createQueryClient, dehydrate, dehydrateStream, feature, focusRefetch, getData, group, hydrate, infiniteQueryOptions, invalidateAll, invalidateMany, invalidateOne, isFetching, link, load, polling, prefetch, queryOptions, recommended, reconnectRefetch, removeAll, removeMany, removeOne, resetAll, resetMany, resetOne, retry, revalidate, setData, skipToken, swr, timeout, waterfallHandle };
|
|
19
|
+
export { type ClientFor, type Clock, type DataOf, type DehydrateOptions, type DehydratedEntry, type DehydratedResult, type DehydratedState, type DehydratedStream, type Feature, type Group, type InfiniteData, type InfiniteQueryFactory, type InfiniteQueryFunctionContext, type InfiniteQueryOptions, type InfiniteQueryOptionsBuilder, type InputOf, type Link, type LoadEntry, type LoadEntryOptions, type Loaded, type Operation, type PageControls, type PageDirection, type PageState, type PartialInput, type QueryClient, type QueryClientConfig, type QueryFactory, type QueryFunctionContext, type QueryHandle, type QueryInfo, type QueryKey, type QueryMeta, type QueryOptions, type QueryOptionsBuilder, QueryTimeoutError, type Recommended, RedactedError, type RetryOptions, type SingleQueryFactory, type StreamOptions, type Target, type Thenable, abortError, bindInfiniteQueryOptions, bindQueryOptions, canDehydrate, createQueryClient, dehydrate, dehydrateStream, feature, fetchNextPage, fetchPreviousPage, focusRefetch, getData, group, hasNextPage, hasPreviousPage, hydrate, infiniteQueryOptions, invalidateAll, invalidateMany, invalidateOne, isFetching, link, load, polling, prefetch, queryOptions, recommended, reconnectRefetch, removeAll, removeMany, removeOne, resetAll, resetMany, resetOne, retry, revalidate, setData, skipToken, swr, timeout, waterfallHandle };
|
package/dist/index.mjs
CHANGED
|
@@ -7,9 +7,10 @@ import { reconnectRefetch } from "./features/reconnect-refetch/reconnect-refetch
|
|
|
7
7
|
import { polling } from "./features/polling/polling.mjs";
|
|
8
8
|
import { RedactedError, canDehydrate, dehydrate, dehydrateStream, hydrate } from "./hydration/hydration.mjs";
|
|
9
9
|
import { bindInfiniteQueryOptions, infiniteQueryOptions } from "./infinite/infinite.mjs";
|
|
10
|
+
import { fetchNextPage, fetchPreviousPage, hasNextPage, hasPreviousPage } from "./infinite/paging.mjs";
|
|
10
11
|
import { retry } from "./links/retry/retry.mjs";
|
|
11
12
|
import { QueryTimeoutError, timeout } from "./links/timeout/timeout.mjs";
|
|
12
13
|
import { load, prefetch, revalidate, skipToken, swr, waterfallHandle } from "./load.mjs";
|
|
13
14
|
import { recommended } from "./presets.mjs";
|
|
14
15
|
import { getData, invalidateAll, invalidateMany, invalidateOne, isFetching, removeAll, removeMany, removeOne, resetAll, resetMany, resetOne, setData } from "./verbs.mjs";
|
|
15
|
-
export { QueryTimeoutError, RedactedError, abortError, bindInfiniteQueryOptions, bindQueryOptions, canDehydrate, createQueryClient, dehydrate, dehydrateStream, feature, focusRefetch, getData, group, hydrate, infiniteQueryOptions, invalidateAll, invalidateMany, invalidateOne, isFetching, link, load, polling, prefetch, queryOptions, recommended, reconnectRefetch, removeAll, removeMany, removeOne, resetAll, resetMany, resetOne, retry, revalidate, setData, skipToken, swr, timeout, waterfallHandle };
|
|
16
|
+
export { QueryTimeoutError, RedactedError, abortError, bindInfiniteQueryOptions, bindQueryOptions, canDehydrate, createQueryClient, dehydrate, dehydrateStream, feature, fetchNextPage, fetchPreviousPage, focusRefetch, getData, group, hasNextPage, hasPreviousPage, hydrate, infiniteQueryOptions, invalidateAll, invalidateMany, invalidateOne, isFetching, link, load, polling, prefetch, queryOptions, recommended, reconnectRefetch, removeAll, removeMany, removeOne, resetAll, resetMany, resetOne, retry, revalidate, setData, skipToken, swr, timeout, waterfallHandle };
|