react-fate 0.1.3 → 1.0.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 (38) hide show
  1. package/README.md +810 -129
  2. package/docs/api/functions/FateClient.md +23 -0
  3. package/docs/api/functions/clientRoot.md +27 -0
  4. package/docs/api/functions/createClient.md +21 -0
  5. package/docs/api/functions/createHTTPTransport.md +51 -0
  6. package/docs/api/functions/createTRPCTransport.md +46 -0
  7. package/docs/api/functions/mutation.md +32 -0
  8. package/docs/api/functions/useFateClient.md +17 -0
  9. package/docs/api/functions/useListView.md +28 -0
  10. package/docs/api/functions/useLiveListView.md +28 -0
  11. package/docs/api/functions/useLiveView.md +38 -0
  12. package/docs/api/functions/useRequest.md +38 -0
  13. package/docs/api/functions/useView.md +37 -0
  14. package/docs/api/functions/view.md +26 -0
  15. package/docs/api/index.md +35 -0
  16. package/docs/api/type-aliases/ConnectionRef.md +13 -0
  17. package/docs/api/type-aliases/InferFateAPI.md +11 -0
  18. package/docs/api/type-aliases/ViewRef.md +13 -0
  19. package/docs/api/variables/toEntityId.md +21 -0
  20. package/docs/guide/actions.md +263 -0
  21. package/docs/guide/core-concepts.md +22 -0
  22. package/docs/guide/getting-started.md +57 -0
  23. package/docs/guide/list-views.md +86 -0
  24. package/docs/guide/live-views.md +245 -0
  25. package/docs/guide/requests.md +130 -0
  26. package/docs/guide/server-integration.md +630 -0
  27. package/docs/guide/views.md +278 -0
  28. package/docs/guide/void-integration.md +167 -0
  29. package/docs/index.md +4 -0
  30. package/lib/cli.d.mts +1 -1
  31. package/lib/cli.mjs +1 -2
  32. package/lib/client.d.mts +7 -0
  33. package/lib/client.mjs +2 -0
  34. package/lib/index.d.mts +41 -17
  35. package/lib/index.mjs +96 -46
  36. package/lib/vite.d.mts +12 -0
  37. package/lib/vite.mjs +8 -0
  38. package/package.json +17 -6
@@ -0,0 +1,130 @@
1
+ # Requests
2
+
3
+ ## Requesting Lists
4
+
5
+ The `useRequest` hook can be used to declare our data needs for a specific screen or component tree. At the root of our app, we can request a list of posts like this:
6
+
7
+ ```tsx
8
+ import { useRequest } from 'react-fate';
9
+ import { PostCard, PostView } from './PostCard.tsx';
10
+
11
+ export function App() {
12
+ const { posts } = useRequest({ posts: { list: PostView } });
13
+ return posts.map((post) => <PostCard key={post.id} post={post} />);
14
+ }
15
+ ```
16
+
17
+ This component suspends or throws errors, which bubble up to the nearest error boundary. Wrap your component tree with `ErrorBoundary` and `Suspense` components to show error and loading states:
18
+
19
+ ```tsx
20
+ <ErrorBoundary FallbackComponent={ErrorComponent}>
21
+ <Suspense fallback={<div>Loading…</div>}>
22
+ <App />
23
+ </Suspense>
24
+ </ErrorBoundary>
25
+ ```
26
+
27
+ > [!NOTE]
28
+ >
29
+ > `useRequest` might issue multiple requests which are automatically batched together by tRPC's [HTTP Batch Link](https://trpc.io/docs/client/links/httpBatchLink) into a single network request.
30
+
31
+ ## Requesting Objects by ID
32
+
33
+ If you want to fetch data for a single object instead of a list, you can specify the `id` and the associated `view` like this:
34
+
35
+ ```tsx
36
+ const { post } = useRequest({
37
+ post: { id: '12', view: PostView },
38
+ });
39
+ ```
40
+
41
+ If you want to fetch multiple objects by their IDs, you can use the `ids` field:
42
+
43
+ ```tsx
44
+ const { posts } = useRequest({
45
+ posts: { ids: ['6', '7'], view: PostView },
46
+ });
47
+ ```
48
+
49
+ ## Other Types of Requests
50
+
51
+ For any other queries, pass only the `type` and `view`:
52
+
53
+ ```tsx
54
+ const { viewer } = useRequest({
55
+ viewer: { view: UserView },
56
+ });
57
+ ```
58
+
59
+ ## Request Arguments
60
+
61
+ You can pass arguments to `useRequest` calls. This is useful for pagination, filtering, or sorting. For example, to fetch the first 10 posts, you can do the following:
62
+
63
+ ```tsx
64
+ const { posts } = useRequest({
65
+ posts: {
66
+ args: { first: 10 },
67
+ list: PostView,
68
+ },
69
+ });
70
+ ```
71
+
72
+ Request arguments are part of the cache key. Two list requests for the same root with different filters or sorting arguments keep separate list state, and cursor arguments are merged into the same list when you load more pages. The selected view is part of the key as well: requesting `PostCardView` and `PostDetailView` can share normalized records, but fate still tracks whether the specific fields for each request are present.
73
+
74
+ ## Request Modes
75
+
76
+ `useRequest` supports different request modes to control caching and data freshness. The available modes are:
77
+
78
+ - `cache-first` (_default_): Returns data from the cache if available, otherwise fetches from the network.
79
+ - `stale-while-revalidate`: Returns data from the cache and simultaneously fetches fresh data from the network.
80
+ - `network-only`: Always fetches data from the network, bypassing the cache.
81
+
82
+ You can pass the request mode as an option to `useRequest`:
83
+
84
+ ```tsx
85
+ const { posts } = useRequest(
86
+ {
87
+ posts: { list: PostView },
88
+ },
89
+ {
90
+ mode: 'stale-while-revalidate',
91
+ },
92
+ );
93
+ ```
94
+
95
+ ## Cache Lifetime
96
+
97
+ fate stores records in a normalized cache keyed by `__typename` and `id`. Lists and root queries point at those records, and views read from the normalized cache. When a `useRequest` call is mounted, fate retains the request so the records and lists needed by that screen stay in memory. When the component unmounts, the request is released and fate schedules garbage collection.
98
+
99
+ Released requests are kept in a small release buffer before their data becomes collectible. This makes common route transitions cheap: navigating away from a screen and quickly coming back usually reuses the cached records instead of refetching them. The default release buffer stores the 10 most recently released requests.
100
+
101
+ You can tune the buffer when creating the client:
102
+
103
+ ```tsx
104
+ const fate = createClient({
105
+ gcReleaseBufferSize: 20,
106
+ roots,
107
+ transport,
108
+ types,
109
+ });
110
+ ```
111
+
112
+ Set `gcReleaseBufferSize` to `0` in tests or very memory-sensitive environments when released screens should be collected immediately.
113
+
114
+ `cache-first` request handles are stable while their request is cached. If garbage collection later removes the data for a fulfilled request, the next `cache-first` request automatically fetches it again rather than returning stale references.
115
+
116
+ If you call `fate.request(...)` outside React and need the result to stay in memory across manual `gc()` calls, retain the same request for the lifetime of that work:
117
+
118
+ ```tsx
119
+ const request = { posts: { list: PostView } };
120
+ const retained = fate.retain(request);
121
+
122
+ try {
123
+ const { posts } = await fate.request(request);
124
+ // Use posts while this request is retained.
125
+ } finally {
126
+ retained.dispose();
127
+ }
128
+ ```
129
+
130
+ Garbage collection waits for active optimistic updates to settle before sweeping records. This keeps temporary optimistic records and their list positions stable while mutations are still pending.