react-fate 1.2.0 → 1.3.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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **FateClient**(`__namedParameters`): `Element`
4
4
 
5
- Defined in: [packages/react-fate/src/context.tsx:17](https://github.com/nkzw-tech/fate/blob/92f28ac4263e4f242ab8546c3bc2123a24b18461/packages/react-fate/src/context.tsx#L17)
5
+ Defined in: [packages/react-fate/src/context.tsx:17](https://github.com/nkzw-tech/fate/blob/4876b00b02cd1ef9ae7fd82b8a3c27d82fc6c232/packages/react-fate/src/context.tsx#L17)
6
6
 
7
7
  Provider component that supplies a configured `FateClient` to React hooks.
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **useFateClient**\<`T`\>(): `FateClient`\<`T`\[`0`\], `T`\[`1`\]\>
4
4
 
5
- Defined in: [packages/react-fate/src/context.tsx:30](https://github.com/nkzw-tech/fate/blob/92f28ac4263e4f242ab8546c3bc2123a24b18461/packages/react-fate/src/context.tsx#L30)
5
+ Defined in: [packages/react-fate/src/context.tsx:30](https://github.com/nkzw-tech/fate/blob/4876b00b02cd1ef9ae7fd82b8a3c27d82fc6c232/packages/react-fate/src/context.tsx#L30)
6
6
 
7
7
  Returns the nearest `FateClient` from context.
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **useListView**\<`C`\>(`selection`, `connection`): \[`ConnectionItems`\<`ResolvedConnection`\<`C`\>\>, `LoadMoreFn` \| `null`, `LoadMoreFn` \| `null`\]
4
4
 
5
- Defined in: [packages/react-fate/src/useListView.tsx:19](https://github.com/nkzw-tech/fate/blob/92f28ac4263e4f242ab8546c3bc2123a24b18461/packages/react-fate/src/useListView.tsx#L19)
5
+ Defined in: [packages/react-fate/src/useListView.tsx:19](https://github.com/nkzw-tech/fate/blob/4876b00b02cd1ef9ae7fd82b8a3c27d82fc6c232/packages/react-fate/src/useListView.tsx#L19)
6
6
 
7
7
  Subscribes to a connection field, returning the current items and pagination
8
8
  helpers to load the next or previous page.
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **useLiveListView**\<`C`\>(`selection`, `connection`): \[`ConnectionItems`\<`ResolvedConnection`\<`C`\>\>, `LoadMoreFn` \| `null`, `LoadMoreFn` \| `null`\]
4
4
 
5
- Defined in: [packages/react-fate/src/useLiveListView.tsx:19](https://github.com/nkzw-tech/fate/blob/92f28ac4263e4f242ab8546c3bc2123a24b18461/packages/react-fate/src/useLiveListView.tsx#L19)
5
+ Defined in: [packages/react-fate/src/useLiveListView.tsx:19](https://github.com/nkzw-tech/fate/blob/4876b00b02cd1ef9ae7fd82b8a3c27d82fc6c232/packages/react-fate/src/useLiveListView.tsx#L19)
6
6
 
7
7
  Subscribes to a connection field, returning live-updating items and pagination
8
8
  helpers to load the next or previous page.
@@ -4,7 +4,7 @@
4
4
 
5
5
  > **useLiveView**\<`V`, `R`\>(`view`, `ref`): `R` *extends* `null` ? `null` : `Readonly`\<`ViewSelection`\<`V`\> *extends* `Selection`\<`ViewEntityWithTypename`\<`V`\>\> ? `Mask`\<`ViewEntityWithTypename`\<`V`\>, \{ \[K in string \| number \| symbol as K extends "\_\_typename" ? never : K\]?: DeferrableSelectionFieldValue\<ViewEntityWithTypename\<V\>, K\> \} & `object` & `SelectionViewSpread`\<`ViewEntityWithTypename`\<`V`\>\> & `ViewSelection`\<`V`\>\> : `ViewEntityWithTypename`\<`V`\> & `object`\>
6
6
 
7
- Defined in: [packages/react-fate/src/useLiveView.tsx:27](https://github.com/nkzw-tech/fate/blob/92f28ac4263e4f242ab8546c3bc2123a24b18461/packages/react-fate/src/useLiveView.tsx#L27)
7
+ Defined in: [packages/react-fate/src/useLiveView.tsx:27](https://github.com/nkzw-tech/fate/blob/4876b00b02cd1ef9ae7fd82b8a3c27d82fc6c232/packages/react-fate/src/useLiveView.tsx#L27)
8
8
 
9
9
  Resolves a reference against a view and subscribes to live server updates for
10
10
  that selection.
@@ -43,7 +43,7 @@ const post = useLiveView(PostView, postRef);
43
43
 
44
44
  > **useLiveView**\<`V`, `R`\>(`view`, `ref`): `R` *extends* `null` ? `null` : `Readonly`\<`ViewSelection`\<`V`\> *extends* `Selection`\<`ViewEntityWithTypename`\<`V`\>\> ? `Mask`\<`ViewEntityWithTypename`\<`V`\>, \{ \[K in string \| number \| symbol as K extends "\_\_typename" ? never : K\]?: DeferrableSelectionFieldValue\<ViewEntityWithTypename\<V\>, K\> \} & `object` & `SelectionViewSpread`\<`ViewEntityWithTypename`\<`V`\>\> & `ViewSelection`\<`V`\>\> : `ViewEntityWithTypename`\<`V`\> & `object`\>
45
45
 
46
- Defined in: [packages/react-fate/src/useLiveView.tsx:31](https://github.com/nkzw-tech/fate/blob/92f28ac4263e4f242ab8546c3bc2123a24b18461/packages/react-fate/src/useLiveView.tsx#L31)
46
+ Defined in: [packages/react-fate/src/useLiveView.tsx:31](https://github.com/nkzw-tech/fate/blob/4876b00b02cd1ef9ae7fd82b8a3c27d82fc6c232/packages/react-fate/src/useLiveView.tsx#L31)
47
47
 
48
48
  Resolves a reference against a view and subscribes to live server updates for
49
49
  that selection.
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **useRequest**\<`R`, `O`\>(`request`, `options?`): `RequestResult`\<`O`, `R`\>
4
4
 
5
- Defined in: [packages/react-fate/src/useRequest.tsx:25](https://github.com/nkzw-tech/fate/blob/92f28ac4263e4f242ab8546c3bc2123a24b18461/packages/react-fate/src/useRequest.tsx#L25)
5
+ Defined in: [packages/react-fate/src/useRequest.tsx:25](https://github.com/nkzw-tech/fate/blob/4876b00b02cd1ef9ae7fd82b8a3c27d82fc6c232/packages/react-fate/src/useRequest.tsx#L25)
6
6
 
7
7
  Declares the data a screen needs and kicks off fetching, suspending while the
8
8
  request resolves.
@@ -4,7 +4,7 @@
4
4
 
5
5
  > **useView**\<`V`, `R`\>(`view`, `ref`): `R` *extends* `null` ? `null` : `Readonly`\<`ViewSelection`\<`V`\> *extends* `Selection`\<`ViewEntityWithTypename`\<`V`\>\> ? `Mask`\<`ViewEntityWithTypename`\<`V`\>, \{ \[K in string \| number \| symbol as K extends "\_\_typename" ? never : K\]?: DeferrableSelectionFieldValue\<ViewEntityWithTypename\<V\>, K\> \} & `object` & `SelectionViewSpread`\<`ViewEntityWithTypename`\<`V`\>\> & `ViewSelection`\<`V`\>\> : `ViewEntityWithTypename`\<`V`\> & `object`\>
6
6
 
7
- Defined in: [packages/react-fate/src/useView.tsx:40](https://github.com/nkzw-tech/fate/blob/92f28ac4263e4f242ab8546c3bc2123a24b18461/packages/react-fate/src/useView.tsx#L40)
7
+ Defined in: [packages/react-fate/src/useView.tsx:40](https://github.com/nkzw-tech/fate/blob/4876b00b02cd1ef9ae7fd82b8a3c27d82fc6c232/packages/react-fate/src/useView.tsx#L40)
8
8
 
9
9
  Resolves a reference against a view and subscribes to updates for that selection.
10
10
 
@@ -42,7 +42,7 @@ const post = useView(PostView, postRef);
42
42
 
43
43
  > **useView**\<`V`, `R`\>(`view`, `ref`): `R` *extends* `null` ? `null` : `Readonly`\<`ViewSelection`\<`V`\> *extends* `Selection`\<`ViewEntityWithTypename`\<`V`\>\> ? `Mask`\<`ViewEntityWithTypename`\<`V`\>, \{ \[K in string \| number \| symbol as K extends "\_\_typename" ? never : K\]?: DeferrableSelectionFieldValue\<ViewEntityWithTypename\<V\>, K\> \} & `object` & `SelectionViewSpread`\<`ViewEntityWithTypename`\<`V`\>\> & `ViewSelection`\<`V`\>\> : `ViewEntityWithTypename`\<`V`\> & `object`\>
44
44
 
45
- Defined in: [packages/react-fate/src/useView.tsx:44](https://github.com/nkzw-tech/fate/blob/92f28ac4263e4f242ab8546c3bc2123a24b18461/packages/react-fate/src/useView.tsx#L44)
45
+ Defined in: [packages/react-fate/src/useView.tsx:44](https://github.com/nkzw-tech/fate/blob/4876b00b02cd1ef9ae7fd82b8a3c27d82fc6c232/packages/react-fate/src/useView.tsx#L44)
46
46
 
47
47
  Resolves a reference against a view and subscribes to updates for that selection.
48
48
 
@@ -80,7 +80,7 @@ const post = useView(PostView, postRef);
80
80
 
81
81
  > **useView**\<`V`\>(`view`, `ref`): `Readonly`\<`ViewSelection`\<`V`\> *extends* `Selection`\<`ViewEntityWithTypename`\<`V`\>\> ? `Mask`\<`ViewEntityWithTypename`\<`V`\>, \{ \[K in string \| number \| symbol as K extends "\_\_typename" ? never : K\]?: DeferrableSelectionFieldValue\<ViewEntityWithTypename\<V\>, K\> \} & `object` & `SelectionViewSpread`\<`ViewEntityWithTypename`\<`V`\>\> & `ViewSelection`\<`V`\>\> : `ViewEntityWithTypename`\<`V`\> & `object`\> \| `null`
82
82
 
83
- Defined in: [packages/react-fate/src/useView.tsx:48](https://github.com/nkzw-tech/fate/blob/92f28ac4263e4f242ab8546c3bc2123a24b18461/packages/react-fate/src/useView.tsx#L48)
83
+ Defined in: [packages/react-fate/src/useView.tsx:48](https://github.com/nkzw-tech/fate/blob/4876b00b02cd1ef9ae7fd82b8a3c27d82fc6c232/packages/react-fate/src/useView.tsx#L48)
84
84
 
85
85
  Resolves a reference against a view and subscribes to updates for that selection.
86
86
 
@@ -0,0 +1,143 @@
1
+ # Cloudflare Integration
2
+
3
+ `cf-fate` is the first-class Cloudflare Workers adapter for Fate native HTTP transport and live views.
4
+
5
+ Use it when your backend runs directly on Cloudflare Workers and you want fate live views without adopting the Void platform.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ pnpm add @nkzw/fate react-fate cf-fate drizzle-orm
11
+ pnpm add -D wrangler
12
+ ```
13
+
14
+ ## Server Setup
15
+
16
+ Create a Cloudflare live stream and pass its Fate live facade to `createFateServer`.
17
+
18
+ ```ts
19
+ // src/fate/live.ts
20
+ import { defineCloudflareFateLiveStream } from 'cf-fate/server';
21
+
22
+ export const fateStream = defineCloudflareFateLiveStream({
23
+ allowAnonymousControl: true,
24
+ binding: 'FATE_LIVE',
25
+ id: 'fate',
26
+ });
27
+ ```
28
+
29
+ ```ts
30
+ // src/fate/server.ts
31
+ import { createFateServer } from '@nkzw/fate/server';
32
+ import { createCloudflareFateLive } from 'cf-fate/server';
33
+
34
+ export const fateLive = createCloudflareFateLive();
35
+ export const { live } = fateLive;
36
+
37
+ export const fateServer = createFateServer({
38
+ live,
39
+ // context,
40
+ // roots,
41
+ // sources,
42
+ });
43
+ ```
44
+
45
+ Publish from mutations through the normal Fate live bus:
46
+
47
+ ```ts
48
+ live.update('Post', postId, { changed: ['likes'] });
49
+ live.connection('Post.comments', { id: postId }).appendNode('Comment', commentId);
50
+ ```
51
+
52
+ ## Worker Routes
53
+
54
+ Expose one route for Fate RPC and one route for the SSE live stream.
55
+
56
+ ```ts
57
+ import {
58
+ createCloudflareFateLiveDurableObject,
59
+ defineCloudflareFateLiveRoute,
60
+ defineCloudflareFateRoute,
61
+ } from 'cf-fate/server';
62
+ import { fateStream } from './fate/live';
63
+ import { fateLive, fateServer } from './fate/server';
64
+
65
+ const fateRoute = defineCloudflareFateRoute(fateServer, fateLive, { stream: fateStream });
66
+ const fateLiveRoute = defineCloudflareFateLiveRoute(fateStream);
67
+
68
+ export const FateLiveDurableObject = createCloudflareFateLiveDurableObject({
69
+ binding: 'FATE_LIVE',
70
+ });
71
+
72
+ export default {
73
+ fetch(request, env, ctx) {
74
+ const url = new URL(request.url);
75
+ if (url.pathname === '/fate') {
76
+ return fateRoute.fetch(request, env, ctx);
77
+ }
78
+ if (url.pathname === '/fate-live') {
79
+ return fateLiveRoute.fetch(request, env, ctx);
80
+ }
81
+ return new Response('Not Found', { status: 404 });
82
+ },
83
+ };
84
+ ```
85
+
86
+ ## Wrangler
87
+
88
+ Add a Durable Object binding and migration. `cf-fate` uses `node:async_hooks`, so the Worker must enable Node compatibility.
89
+
90
+ ```jsonc
91
+ {
92
+ "compatibility_flags": ["nodejs_compat"],
93
+ "durable_objects": {
94
+ "bindings": [
95
+ {
96
+ "name": "FATE_LIVE",
97
+ "class_name": "FateLiveDurableObject",
98
+ },
99
+ ],
100
+ },
101
+ "migrations": [
102
+ {
103
+ "tag": "fate-live-v1",
104
+ "new_sqlite_classes": ["FateLiveDurableObject"],
105
+ },
106
+ ],
107
+ }
108
+ ```
109
+
110
+ ## Client
111
+
112
+ Use the Cloudflare transport in the Fate Vite plugin:
113
+
114
+ ```ts
115
+ import { fate } from 'react-fate/vite';
116
+
117
+ fate({
118
+ module: './src/fate/server.ts',
119
+ transport: 'cloudflare',
120
+ });
121
+ ```
122
+
123
+ Then point the generated client at the Worker endpoints:
124
+
125
+ ```tsx
126
+ import { FateClient } from 'react-fate';
127
+ import { createFateClient } from 'react-fate/client';
128
+
129
+ const fate = createFateClient({
130
+ liveUrl: 'http://localhost:8787/fate-live',
131
+ url: 'http://localhost:8787/fate',
132
+ });
133
+
134
+ export function App({ children }) {
135
+ return <FateClient client={fate}>{children}</FateClient>;
136
+ }
137
+ ```
138
+
139
+ ## Semantics
140
+
141
+ `cf-fate` uses one browser `EventSource` per Fate client and multiplexes entity and connection topics over that stream. Durable Objects keep connection and topic subscription state so later requests, mutations, scheduled handlers, and queue consumers can publish to already-connected clients.
142
+
143
+ Delivery is at-most-once. Events are ordered within one topic, but events are not durably replayed after a disconnect. Use authoritative refetching or application-owned replay storage if missed events must be recovered.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-fate",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "fate is a modern data client for React.",
5
5
  "homepage": "https://github.com/nkzw-tech/fate",
6
6
  "license": "MIT",
@@ -40,7 +40,7 @@
40
40
  }
41
41
  },
42
42
  "dependencies": {
43
- "@nkzw/fate": "^1.2.0"
43
+ "@nkzw/fate": "^1.3.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/react": "^19.2.16",