@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.
Files changed (38) hide show
  1. package/CHANGELOG.md +36 -2
  2. package/dist/client.d.mts +38 -5
  3. package/dist/client.mjs +37 -6
  4. package/dist/entry.d.mts +7 -0
  5. package/dist/entry.mjs +16 -2
  6. package/dist/features/focus-refetch/focus-refetch.d.mts +2 -0
  7. package/dist/features/focus-refetch/focus-refetch.mjs +2 -0
  8. package/dist/features/polling/polling.d.mts +5 -1
  9. package/dist/features/polling/polling.mjs +5 -1
  10. package/dist/features/reconnect-refetch/reconnect-refetch.d.mts +2 -0
  11. package/dist/features/reconnect-refetch/reconnect-refetch.mjs +2 -0
  12. package/dist/hydration/hydration.d.mts +38 -3
  13. package/dist/hydration/hydration.mjs +16 -2
  14. package/dist/index.d.mts +3 -2
  15. package/dist/index.mjs +2 -1
  16. package/dist/infinite/infinite.d.mts +37 -15
  17. package/dist/infinite/infinite.mjs +41 -8
  18. package/dist/infinite/paging.d.mts +71 -0
  19. package/dist/infinite/paging.mjs +62 -0
  20. package/dist/internal.d.mts +3 -3
  21. package/dist/internal.mjs +3 -3
  22. package/dist/keys/keys.d.mts +9 -1
  23. package/dist/keys/targets.d.mts +8 -2
  24. package/dist/links/retry/retry.d.mts +7 -0
  25. package/dist/links/retry/retry.mjs +2 -0
  26. package/dist/links/timeout/timeout.d.mts +10 -2
  27. package/dist/links/timeout/timeout.mjs +10 -2
  28. package/dist/load.d.mts +28 -3
  29. package/dist/load.mjs +26 -3
  30. package/dist/options.d.mts +79 -9
  31. package/dist/options.mjs +7 -3
  32. package/dist/presets.d.mts +7 -1
  33. package/dist/presets.mjs +2 -0
  34. package/dist/root.d.mts +5 -1
  35. package/dist/thenable.d.mts +2 -0
  36. package/dist/verbs.d.mts +56 -15
  37. package/dist/verbs.mjs +34 -6
  38. 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
- * greenfield rewrite on a promise kernel, with load() handles and opt-in behaviors ([#230](https://github.com/KATT/raf-query/issues/230))
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
- * 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))
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
- /** Time and timers, injectable so tests control them without patching globals. */
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
- /** One request, as links see it. `TMeta` is what the link declares. */
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
- /** Cache events: entries added, updated, removed, or gaining and losing readers. */
115
- subscribe(listener: (event: ClientEvent) => void, options?: SubscribeOptions): () => void;
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": /* @__PURE__ */ new Map(),
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) => events.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
- const controller = new AbortController();
69
- for (const start of client.config.features ?? []) start(client, controller.signal);
70
- return () => controller.abort();
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
- /** Refetch read queries every `meta.refetchInterval` ms. */
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
- /** Refetch read queries every `meta.refetchInterval` ms. */
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
- /** What a dehydrated pending entry's promise resolves to. */
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
- /** The default filter: entries with data or a request in flight. */
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
- /** Snapshot the client's entries for transfer. */
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
- /** The default filter: entries with data or a request in flight. */
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
- /** Snapshot the client's entries for transfer. */
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
- import { ClientFor, PartialInput, getData, invalidateAll, invalidateMany, invalidateOne, isFetching, removeAll, removeMany, removeOne, resetAll, resetMany, resetOne, setData } from "./verbs.mjs";
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 };