@raf-query/react 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.
Files changed (46) hide show
  1. package/CHANGELOG.md +39 -1
  2. package/README.md +32 -59
  3. package/dist/bind.d.mts +21 -0
  4. package/dist/bind.mjs +23 -0
  5. package/dist/browser-render.mjs +46 -0
  6. package/dist/devtools.d.mts +42 -2
  7. package/dist/devtools.mjs +244 -1
  8. package/dist/hydration-boundary/hydrate.mjs +10 -13
  9. package/dist/hydration-boundary/hydration-boundary-react-server.d.mts +6 -0
  10. package/dist/hydration-boundary/hydration-boundary-react-server.mjs +20 -9
  11. package/dist/hydration-boundary/hydration-boundary.d.mts +15 -28
  12. package/dist/hydration-boundary/hydration-boundary.mjs +7 -26
  13. package/dist/index-react-server.d.mts +7 -6
  14. package/dist/index-react-server.mjs +4 -6
  15. package/dist/index-shared.d.mts +5 -6
  16. package/dist/index-shared.mjs +3 -6
  17. package/dist/index.d.mts +7 -6
  18. package/dist/index.mjs +5 -4
  19. package/dist/provider.d.mts +11 -5
  20. package/dist/provider.mjs +12 -9
  21. package/dist/react-server-hooks.d.mts +43 -0
  22. package/dist/react-server-hooks.mjs +45 -0
  23. package/dist/tanstack-router-browser.d.mts +2 -0
  24. package/dist/tanstack-router-browser.mjs +2 -0
  25. package/dist/tanstack-router-shared.d.mts +9 -7
  26. package/dist/tanstack-router-shared.mjs +12 -22
  27. package/dist/tanstack-router.d.mts +4 -2
  28. package/dist/tanstack-router.mjs +12 -14
  29. package/dist/tracked.d.mts +1 -0
  30. package/dist/tracked.mjs +65 -0
  31. package/dist/use-infinite-query.d.mts +23 -0
  32. package/dist/use-infinite-query.mjs +30 -0
  33. package/dist/use-is-fetching.d.mts +7 -15
  34. package/dist/use-is-fetching.mjs +12 -30
  35. package/dist/use-query.d.mts +52 -50
  36. package/dist/use-query.mjs +112 -47
  37. package/package.json +10 -9
  38. package/dist/devtools-panel.d.mts +0 -38
  39. package/dist/devtools-panel.mjs +0 -896
  40. package/dist/devtools-store.mjs +0 -104
  41. package/dist/hydration-boundary/sent.mjs +0 -16
  42. package/dist/query-provider/browser-requests.mjs +0 -38
  43. package/dist/query-provider/query-provider.d.mts +0 -21
  44. package/dist/query-provider/query-provider.mjs +0 -33
  45. package/dist/use-waterfall.d.mts +0 -18
  46. package/dist/use-waterfall.mjs +0 -41
@@ -1,104 +0,0 @@
1
- import { Query } from "@raf-query/core";
2
- import { useSyncExternalStore } from "react";
3
- //#region src/devtools-store.ts
4
- const statuses = [
5
- "fetching",
6
- "error",
7
- "stale",
8
- "fresh",
9
- "inactive"
10
- ];
11
- const sortOrders = [
12
- "status",
13
- "hash",
14
- "updated"
15
- ];
16
- const stores = /* @__PURE__ */ new WeakMap();
17
- function statusOf(query) {
18
- const state = Query.getUnsafe(query);
19
- if (state.isFetching) return "fetching";
20
- if (state.status === "error") return "error";
21
- if (Query.observerCountUnsafe(query) === 0) return "inactive";
22
- return Query.isStaleUnsafe(query) ? "stale" : "fresh";
23
- }
24
- function rowOf(query) {
25
- return {
26
- hash: query.hash,
27
- observers: Query.observerCountUnsafe(query),
28
- query,
29
- state: Query.getUnsafe(query),
30
- status: statusOf(query)
31
- };
32
- }
33
- function createStore(client) {
34
- const listeners = /* @__PURE__ */ new Set();
35
- let version = 0;
36
- let snapshotVersion = -1;
37
- let snapshot = [];
38
- let scheduled = false;
39
- client.subscribe(() => {
40
- version++;
41
- if (scheduled || listeners.size === 0) return;
42
- scheduled = true;
43
- queueMicrotask(() => {
44
- scheduled = false;
45
- for (const listener of listeners) listener();
46
- });
47
- });
48
- return {
49
- getSnapshot: () => {
50
- if (snapshotVersion !== version) {
51
- snapshotVersion = version;
52
- snapshot = client.getAll().map(rowOf);
53
- }
54
- return snapshot;
55
- },
56
- subscribe: (onChange) => {
57
- listeners.add(onChange);
58
- return () => {
59
- listeners.delete(onChange);
60
- };
61
- }
62
- };
63
- }
64
- function storeFor(client) {
65
- let store = stores.get(client);
66
- if (!store) {
67
- store = createStore(client);
68
- stores.set(client, store);
69
- }
70
- return store;
71
- }
72
- /** Every cache entry, re-rendering on each batch of cache events. */
73
- function useQueryRows(client) {
74
- const store = storeFor(client);
75
- return useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
76
- }
77
- function countByStatus(rows) {
78
- const counts = {
79
- error: 0,
80
- fetching: 0,
81
- fresh: 0,
82
- inactive: 0,
83
- stale: 0
84
- };
85
- for (const row of rows) counts[row.status]++;
86
- return counts;
87
- }
88
- function compareRows(sortBy) {
89
- return (a, b) => {
90
- const primary = {
91
- hash: 0,
92
- status: statuses.indexOf(a.status) - statuses.indexOf(b.status),
93
- updated: b.state.updatedAt - a.state.updatedAt
94
- }[sortBy];
95
- return primary === 0 ? a.hash.localeCompare(b.hash) : primary;
96
- };
97
- }
98
- /** Rows whose hash contains `filter` (case-insensitive), sorted. */
99
- function visibleRows(rows, filter, sortBy) {
100
- const needle = filter.trim().toLowerCase();
101
- return rows.filter((row) => row.hash.toLowerCase().includes(needle)).toSorted(compareRows(sortBy));
102
- }
103
- //#endregion
104
- export { countByStatus, sortOrders, statuses, useQueryRows, visibleRows };
@@ -1,16 +0,0 @@
1
- //#region src/hydration-boundary/sent.ts
2
- const sentByClient = /* @__PURE__ */ new WeakMap();
3
- /**
4
- * Hashes of the request client's entries an earlier `HydrationBoundary`
5
- * already sent. Boundaries pass it as `sent`, so each entry crosses once.
6
- */
7
- function sentHashes(client) {
8
- let sent = sentByClient.get(client);
9
- if (!sent) {
10
- sent = /* @__PURE__ */ new Set();
11
- sentByClient.set(client, sent);
12
- }
13
- return sent;
14
- }
15
- //#endregion
16
- export { sentHashes };
@@ -1,38 +0,0 @@
1
- import { Query } from "@raf-query/core";
2
- //#region src/query-provider/browser-requests.ts
3
- /**
4
- * The digest Next.js gives a boundary that renders only in the browser
5
- * (`next/dynamic` with `ssr: false`); it doesn't report those errors.
6
- */
7
- const clientRendering = "BAILOUT_TO_CLIENT_SIDE_RENDERING";
8
- const browserOnly = /* @__PURE__ */ new WeakSet();
9
- /**
10
- * Make a server client's render start no request: it reads what a
11
- * `HydrationBoundary` sent, and anything else loads in the browser.
12
- */
13
- function requestInBrowserOnly(client) {
14
- browserOnly.add(client);
15
- }
16
- /** Whether a render may start `client`'s requests (`useWaterfall`). */
17
- function startsRequests(client) {
18
- return !(client.isServer && browserOnly.has(client));
19
- }
20
- /**
21
- * Thrown by a server render's read of a query no `HydrationBoundary` sent.
22
- * React renders the nearest Suspense fallback, and the browser renders the
23
- * content.
24
- */
25
- var BrowserRenderError = class extends Error {
26
- digest = clientRendering;
27
- constructor(hash) {
28
- super(`Query ${hash} loads in the browser: no HydrationBoundary sent it`);
29
- }
30
- };
31
- /** Throw {@link BrowserRenderError} if reading `query` would start a request here. */
32
- function assertSent(client, query) {
33
- if (startsRequests(client)) return;
34
- const state = Query.getUnsafe(query);
35
- if (!state.hasData && !state.isFetching && state.status !== "error") throw new BrowserRenderError(query.hash);
36
- }
37
- //#endregion
38
- export { assertSent, requestInBrowserOnly, startsRequests };
@@ -1,21 +0,0 @@
1
- import { QueryClientConfig } from "@raf-query/core";
2
- import { ReactNode } from "react";
3
- //#region src/query-provider/query-provider.d.ts
4
- /**
5
- * The query client provider for React Server Components apps. Creates one
6
- * client per server render and one per browser tab. The server render
7
- * starts no request: client components read what `HydrationBoundary` sent,
8
- * and a query nothing sent renders its Suspense fallback there and loads in
9
- * the browser.
10
- *
11
- * ```tsx
12
- * // app/layout.tsx
13
- * <QueryProvider>{props.children}</QueryProvider>
14
- * ```
15
- */
16
- export declare function QueryProvider(props: {
17
- readonly children?: ReactNode;
18
- /** Options for the client it creates. */
19
- readonly config?: QueryClientConfig;
20
- }): import("react").JSX.Element;
21
- //#endregion
@@ -1,33 +0,0 @@
1
- "use client";
2
- import { QueryClientProvider } from "../provider.mjs";
3
- import { requestInBrowserOnly } from "./browser-requests.mjs";
4
- import { QueryClient } from "@raf-query/core";
5
- import { useState } from "react";
6
- import { jsx } from "react/jsx-runtime";
7
- //#region src/query-provider/query-provider.tsx
8
- /**
9
- * The query client provider for React Server Components apps. Creates one
10
- * client per server render and one per browser tab. The server render
11
- * starts no request: client components read what `HydrationBoundary` sent,
12
- * and a query nothing sent renders its Suspense fallback there and loads in
13
- * the browser.
14
- *
15
- * ```tsx
16
- * // app/layout.tsx
17
- * <QueryProvider>{props.children}</QueryProvider>
18
- * ```
19
- */
20
- function QueryProvider(props) {
21
- const config = props.config;
22
- const [client] = useState(() => {
23
- const created = new QueryClient(config);
24
- requestInBrowserOnly(created);
25
- return created;
26
- });
27
- return /* @__PURE__ */ jsx(QueryClientProvider, {
28
- client,
29
- children: props.children
30
- });
31
- }
32
- //#endregion
33
- export { QueryProvider };
@@ -1,18 +0,0 @@
1
- import { InputArgs, QueryFactory, QueryHandle } from "@raf-query/core";
2
- //#region src/use-waterfall.d.ts
3
- /**
4
- * Start a query during render and return its handle, for inputs only known
5
- * at render time (an id from a parent query's data). Each call is a request
6
- * waterfall: prefer starting the query in a loader or server component.
7
- * Like `prefetch` in a loader, it refetches stale cached data in the
8
- * background, once per mount and input. Under `QueryProvider` it
9
- * starts nothing on the server: the reader's Suspense boundary renders its
10
- * fallback there, and the query loads in the browser.
11
- *
12
- * ```tsx
13
- * const author = useWaterfall(authorQuery, { id: post.authorId });
14
- * const [authorPromise] = useQuery(authorQuery, author);
15
- * ```
16
- */
17
- export declare function useWaterfall<TFactory extends QueryFactory>(factory: TFactory, ...args: InputArgs<TFactory>): QueryHandle<TFactory>;
18
- //#endregion
@@ -1,41 +0,0 @@
1
- "use client";
2
- import { useQueryClient } from "./provider.mjs";
3
- import { startsRequests } from "./query-provider/browser-requests.mjs";
4
- import { Query } from "@raf-query/core";
5
- import { useState } from "react";
6
- //#region src/use-waterfall.ts
7
- /**
8
- * First loads a waterfall suspended on. A suspended mount keeps no state, so
9
- * this is how its retry knows the data it finds is the load it just waited
10
- * for, not cached data to revalidate.
11
- */
12
- const waitedFor = /* @__PURE__ */ new WeakSet();
13
- /**
14
- * Start a query during render and return its handle, for inputs only known
15
- * at render time (an id from a parent query's data). Each call is a request
16
- * waterfall: prefer starting the query in a loader or server component.
17
- * Like `prefetch` in a loader, it refetches stale cached data in the
18
- * background, once per mount and input. Under `QueryProvider` it
19
- * starts nothing on the server: the reader's Suspense boundary renders its
20
- * fallback there, and the query loads in the browser.
21
- *
22
- * ```tsx
23
- * const author = useWaterfall(authorQuery, { id: post.authorId });
24
- * const [authorPromise] = useQuery(authorQuery, author);
25
- * ```
26
- */
27
- function useWaterfall(factory, ...args) {
28
- const client = useQueryClient();
29
- const query = client.getQuery(factory, ...args);
30
- const [started, setStarted] = useState();
31
- if (!startsRequests(client)) return query.handle;
32
- const promise = Query.readUnsafe(query);
33
- if (started !== query.hash) {
34
- if (!Query.getUnsafe(query).hasData) waitedFor.add(promise);
35
- else if (!waitedFor.delete(promise)) Query.revalidateUnsafe(query);
36
- setStarted(query.hash);
37
- } else if (Query.getUnsafe(query).hasData) waitedFor.delete(promise);
38
- return query.handle;
39
- }
40
- //#endregion
41
- export { useWaterfall };