dynamodb-reactive 0.1.3 → 0.1.5
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/README.md +114 -24
- package/dist/{chunk-IPEBRXIL.js → chunk-MI2ZLLB2.js} +361 -50
- package/dist/chunk-MI2ZLLB2.js.map +1 -0
- package/dist/client.d.ts +12 -2
- package/dist/client.js +1 -1
- package/dist/infra.js +1 -1
- package/dist/infra.js.map +1 -1
- package/dist/{react-BMZQ8Mth.d.ts → react-B8Q_XoCk.d.ts} +183 -16
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/server.d.ts +41 -13
- package/dist/server.js +95 -10
- package/dist/server.js.map +1 -1
- package/package.json +4 -2
- package/dist/chunk-IPEBRXIL.js.map +0 -1
package/README.md
CHANGED
|
@@ -124,35 +124,125 @@ export async function POST(request: Request) {
|
|
|
124
124
|
}
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
-
### **Step 4:
|
|
127
|
+
### **Step 4: Set Up React Provider**
|
|
128
128
|
|
|
129
129
|
```typescript
|
|
130
|
-
//
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
130
|
+
// app/layout.tsx or providers.tsx
|
|
131
|
+
'use client';
|
|
132
|
+
|
|
133
|
+
import { ReactiveClientProvider } from 'dynamodb-reactive/client';
|
|
134
|
+
|
|
135
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
136
|
+
return (
|
|
137
|
+
<ReactiveClientProvider
|
|
138
|
+
config={{
|
|
139
|
+
url: process.env.NEXT_PUBLIC_WS_URL!,
|
|
140
|
+
httpUrl: '/api/reactive',
|
|
141
|
+
}}
|
|
142
|
+
>
|
|
143
|
+
{children}
|
|
144
|
+
</ReactiveClientProvider>
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### **Step 5: Use React Hooks**
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
'use client';
|
|
153
|
+
|
|
154
|
+
import type { Todo } from './types';
|
|
155
|
+
import type { AppRouter } from './router';
|
|
156
|
+
import { useClient, useConnectionState } from 'dynamodb-reactive/client';
|
|
157
|
+
|
|
158
|
+
export function TodoList() {
|
|
159
|
+
const connectionState = useConnectionState();
|
|
160
|
+
const client = useClient<AppRouter>();
|
|
161
|
+
|
|
162
|
+
// Subscribe to todos - receives real-time updates via WebSocket
|
|
163
|
+
const { data: todos, loading, error } = client.todos.list.useQuery({});
|
|
164
|
+
|
|
165
|
+
// Mutations with automatic optimistic updates
|
|
166
|
+
const createMutation = client.todos.create.useMutation();
|
|
167
|
+
const toggleMutation = client.todos.toggle.useMutation();
|
|
168
|
+
const deleteMutation = client.todos.delete.useMutation();
|
|
169
|
+
|
|
170
|
+
const handleCreate = async (text: string) => {
|
|
171
|
+
await createMutation.mutate({ text });
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const handleToggle = async (id: string) => {
|
|
175
|
+
await toggleMutation.mutate({ id });
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const handleDelete = async (id: string) => {
|
|
179
|
+
await deleteMutation.mutate({ id }); // Removes instantly from UI
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
if (loading) return <div>Loading...</div>;
|
|
183
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
184
|
+
|
|
185
|
+
return (
|
|
186
|
+
<div>
|
|
187
|
+
<p>WebSocket: {connectionState}</p>
|
|
188
|
+
{todos?.map((todo) => (
|
|
189
|
+
<div key={todo.id}>
|
|
190
|
+
<input
|
|
191
|
+
type="checkbox"
|
|
192
|
+
checked={todo.completed}
|
|
193
|
+
onChange={() => handleToggle(todo.id)}
|
|
194
|
+
/>
|
|
195
|
+
<span>{todo.text}</span>
|
|
196
|
+
<button onClick={() => handleDelete(todo.id)}>Delete</button>
|
|
197
|
+
</div>
|
|
198
|
+
))}
|
|
199
|
+
</div>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## **5. Optimistic Updates**
|
|
205
|
+
|
|
206
|
+
All mutations apply **instant** optimistic updates (before HTTP request):
|
|
207
|
+
|
|
208
|
+
| Update Type | Behavior | Example Input |
|
|
209
|
+
| :--- | :--- | :--- |
|
|
210
|
+
| `'merge'` | Find item by `input.id`, merge input fields | `{ id: '123', completed: true }` |
|
|
211
|
+
| `'remove'` | Remove item by `input.id` | `{ id: '123' }` |
|
|
212
|
+
| Custom function | Apply custom logic | `(data, input) => [...]` |
|
|
213
|
+
|
|
214
|
+
**Convention:** `<namespace>.<action>` mutations auto-invalidate `<namespace>.list` subscriptions.
|
|
215
|
+
|
|
216
|
+
**Example - Instant Toggle:**
|
|
217
|
+
```typescript
|
|
218
|
+
// For instant optimistic updates, include the fields you want to change
|
|
219
|
+
const handleToggle = async (todo: Todo) => {
|
|
220
|
+
await updateMutation.mutate({
|
|
221
|
+
id: todo.id,
|
|
222
|
+
completed: !todo.completed // Include new value for instant UI update
|
|
223
|
+
});
|
|
224
|
+
};
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Custom options:**
|
|
228
|
+
```typescript
|
|
229
|
+
const mutation = client.todos.update.useMutation({
|
|
230
|
+
invalidates: 'todos.list', // Override auto-detection
|
|
231
|
+
optimisticUpdate: 'merge', // 'merge' | 'remove' | custom function
|
|
139
232
|
});
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
path: 'todos.create',
|
|
149
|
-
input: { text: 'New todo' },
|
|
233
|
+
|
|
234
|
+
// For creates (no id), provide optimisticData
|
|
235
|
+
const createMutation = client.todos.create.useMutation({
|
|
236
|
+
optimisticData: (input) => ({
|
|
237
|
+
id: `temp-${Date.now()}`,
|
|
238
|
+
...input,
|
|
239
|
+
completed: false,
|
|
240
|
+
createdAt: Date.now(),
|
|
150
241
|
}),
|
|
151
242
|
});
|
|
152
|
-
const { data } = await response.json();
|
|
153
243
|
```
|
|
154
244
|
|
|
155
|
-
## **
|
|
245
|
+
## **6. Database Context Methods**
|
|
156
246
|
|
|
157
247
|
The `ctx.db` object provides these methods:
|
|
158
248
|
|
|
@@ -164,11 +254,11 @@ The `ctx.db` object provides these methods:
|
|
|
164
254
|
| `update(table, key, updates)` | Update item fields |
|
|
165
255
|
| `delete(table, key)` | Delete item |
|
|
166
256
|
|
|
167
|
-
## **
|
|
257
|
+
## **7. Requirements**
|
|
168
258
|
|
|
169
259
|
* Node.js >= 18.0.0
|
|
170
260
|
* TypeScript >= 5.3.0
|
|
171
261
|
|
|
172
|
-
## **
|
|
262
|
+
## **8. License**
|
|
173
263
|
|
|
174
264
|
MIT
|