@mindstudio-ai/remy 0.1.2 → 0.1.4

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.
@@ -125,6 +125,23 @@ Forms should feel like interactions, not paperwork.
125
125
  - Even data entry can be beautiful. Pay attention to alignment, padding,
126
126
  and spacing. Consistency is key.
127
127
 
128
+ ## Data Fetching and Updates
129
+
130
+ The UI should feel instant. Never make the user wait for a server round-trip
131
+ to see the result of their own action.
132
+
133
+ - **Optimistic updates.** When a user adds a row, toggles a setting, or
134
+ submits a form, update the UI immediately and let the backend confirm
135
+ in the background. If the backend fails, revert and show an error.
136
+ - **Use SWR for data fetching** (`useSWR` from the `swr` package). It
137
+ handles caching, revalidation, and stale-while-revalidate out of the box.
138
+ Prefer SWR over manual `useEffect` + `useState` fetch patterns.
139
+ - **Mutate after actions.** After a successful create/update/delete, call
140
+ `mutate()` to revalidate the relevant SWR cache rather than manually
141
+ updating local state.
142
+ - **Skeleton loading.** Show skeletons that mirror the layout on initial
143
+ load. Never show a blank page or centered spinner while data is loading.
144
+
128
145
  ## What Good Looks Like
129
146
 
130
147
  - A dashboard that feels like Linear — clean data, clear hierarchy, every
@@ -143,7 +143,9 @@ const minAmount = 10000;
143
143
  Vendors.filter(v => v.totalCents > minAmount) // captured variables
144
144
  ```
145
145
 
146
- If a predicate can't be compiled to SQL (complex closures, function calls), the SDK falls back to fetching all rows and filtering in JavaScript. A warning is logged.
146
+ **What compiles to SQL** (efficient): equality, comparisons, `&&`/`||`, `.includes()` for arrays and strings, null checks, boolean negation, captured variables.
147
+
148
+ **What falls back to JS** (fetches all rows, filters in memory): `.startsWith()`, regex, computed expressions like `o.a + o.b > 100`, complex closures. A warning is logged when this happens. Avoid these patterns on large tables.
147
149
 
148
150
  ### Time Helpers
149
151
 
@@ -160,17 +162,34 @@ db.ago(db.days(7) + db.hours(12)) // composable — 7.5 days ago
160
162
  Invoices.filter(i => i.dueDate < db.ago(db.days(30)))
161
163
  ```
162
164
 
163
- ### Batch Queries
165
+ ### Batching
164
166
 
165
- Execute multiple queries in a single round-trip:
167
+ `db.batch()` combines multiple operations into a single HTTP round-trip. Every `await` on a table operation is a network call, so batching is critical for performance. Use it whenever you have multiple reads, writes, or a mix of both:
166
168
 
167
169
  ```typescript
168
- const [vendors, orders] = await db.batch(
170
+ // Reads: fetch related data in one call instead of sequential awaits
171
+ const [vendors, orders, invoiceCount] = await db.batch(
169
172
  Vendors.filter(v => v.status === 'approved'),
170
173
  PurchaseOrders.filter(po => po.vendorId === vendorId),
174
+ Invoices.count(i => i.status === 'pending'),
175
+ );
176
+
177
+ // Writes: batch multiple updates instead of awaiting each one in a loop
178
+ const mutations = items.map(item =>
179
+ Orders.update(item.id, { status: 'approved' })
180
+ );
181
+ await db.batch(...mutations);
182
+
183
+ // Mixed: writes execute in order, reads observe prior writes
184
+ const [_, newOrder, pending] = await db.batch(
185
+ Orders.update(id, { status: 'approved' }),
186
+ Orders.push({ item: 'Laptop', amount: 999, status: 'pending', requestedBy: userId }),
187
+ Orders.filter(o => o.status === 'pending').take(10),
171
188
  );
172
189
  ```
173
190
 
191
+ **Always batch instead of sequential awaits.** A loop with `await Table.update()` inside makes N separate HTTP calls. Mapping to mutations and passing them to `db.batch()` makes one.
192
+
174
193
  ## Migrations
175
194
 
176
195
  No migration files. Migrations are automatic:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindstudio-ai/remy",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "MindStudio coding agent",
5
5
  "repository": {
6
6
  "type": "git",