authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-01-29 16:49:46-08:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-01-29 16:57:23-08:00
logb51077c59854543b2c70ea2be825d68cfb567d8c
tree3449d3519625c9bb4232125795e3004322a32d05
parentf62d1ee915bf4e77c8e2d55d1286211289fbdd51
signaturelock-open Commit is signed but in an unrecognized format.

chore: swap arg order


4 files changed, 18 insertions(+), 21 deletions(-)

jsr.json+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1{1{
2 "name": "@clo/react-mutation",2 "name": "@clo/react-mutation",
3 "version": "1.0.0-beta.6",3 "version": "1.0.0-beta.7",
4 "exports": {4 "exports": {
5 ".": "./src/mod.ts",5 ".": "./src/mod.ts",
6 "./tanstack-query.ts": "./src/tanstack-query.ts",6 "./tanstack-query.ts": "./src/tanstack-query.ts",
package.json-1
...@@ -1,6 +1,5 @@...@@ -1,6 +1,5 @@
1{1{
2 "name": "@clo/react-mutation",2 "name": "@clo/react-mutation",
3 "version": "0.1.0",
4 "private": true,3 "private": true,
5 "description": "",4 "description": "",
6 "license": "ISC",5 "license": "ISC",
readme.md+9-9
...@@ -21,7 +21,7 @@ The primary gains React Mutation provides are...@@ -21,7 +21,7 @@ The primary gains React Mutation provides are
21 this power in more detail.21 this power in more detail.
22- Easy debouncing and batching utilities.22- Easy debouncing and batching utilities.
2323
24## Usage24## Setup
2525
26React Mutation starts with a `MutationClient`, which shares global state for an application.26React Mutation starts with a `MutationClient`, which shares global state for an application.
2727
...@@ -61,7 +61,7 @@ export const mutations = new MutationClient({...@@ -61,7 +61,7 @@ export const mutations = new MutationClient({
61});61});
62```62```
6363
64### Declaring Mutations64## Declaring Mutations
6565
66With a mutation client, you can declare mutations with `mutations.define()`.66With a mutation client, you can declare mutations with `mutations.define()`.
67Start with the API call code, and then add an optimistic updater function.67Start with the API call code, and then add an optimistic updater function.
...@@ -121,7 +121,7 @@ export function Example({ id }: { id: string }) {...@@ -121,7 +121,7 @@ export function Example({ id }: { id: string }) {
121```121```
122122
123123
124### Optimistic Updates124## Optimistic Updates
125125
126The `optimistic` function is given an object with the following APIs126The `optimistic` function is given an object with the following APIs
127127
...@@ -132,7 +132,7 @@ The `optimistic` function is given an object with the following APIs...@@ -132,7 +132,7 @@ The `optimistic` function is given an object with the following APIs
132- `onRestore` - add a callback to revert your optimistic update132- `onRestore` - add a callback to revert your optimistic update
133- `onRefetch` - add a callback to fetch data after a success133- `onRefetch` - add a callback to fetch data after a success
134134
135#### React Query Optimistic Helpers135### React Query Optimistic Helpers
136136
137When using React Query, you can opt into some incredible helpers for making it137When using React Query, you can opt into some incredible helpers for making it
138very easy to write Optimistic Updates. Our setup at work is with this client138very easy to write Optimistic Updates. Our setup at work is with this client
...@@ -191,7 +191,7 @@ automatically implement `onRefetch` and `onRestore` callbacks. The current list...@@ -191,7 +191,7 @@ automatically implement `onRefetch` and `onRestore` callbacks. The current list
191 - `objArrayUpdate` - update items in array by `filter` + `update`191 - `objArrayUpdate` - update items in array by `filter` + `update`
192 - `objArrayInsertIndex` - insert an item in an array at an index192 - `objArrayInsertIndex` - insert an item in an array at an index
193193
194### Debouncing194## Debouncing
195195
196By default, a mutation will block the UI (by setting isPending). If you add196By default, a mutation will block the UI (by setting isPending). If you add
197`debounceMs`, the mutation will no longer set isPending. Multiple mutations197`debounceMs`, the mutation will no longer set isPending. Multiple mutations
...@@ -226,7 +226,7 @@ function Item({ id }: { id: string }) {...@@ -226,7 +226,7 @@ function Item({ id }: { id: string }) {
226}226}
227```227```
228228
229### Calling Mutations229## Calling Mutations
230230
231Three methods exist for calling mutations:231Three methods exist for calling mutations:
232232
...@@ -234,7 +234,7 @@ Three methods exist for calling mutations:...@@ -234,7 +234,7 @@ Three methods exist for calling mutations:
234- From a React component: `useMutate(mutDoAction)`234- From a React component: `useMutate(mutDoAction)`
235- From a React Element: `<MutationButton>`235- From a React Element: `<MutationButton>`
236236
237#### The `useMutate` Hook237### The `useMutate` Hook
238238
239The `useMutate(null | Mutation)` react hook returns an object with the following properties.239The `useMutate(null | Mutation)` react hook returns an object with the following properties.
240240
...@@ -269,7 +269,7 @@ return (...@@ -269,7 +269,7 @@ return (
269);269);
270```270```
271271
272#### Mutation Buttons272### Mutation Buttons
273273
274You can wrap your button component with `createMutationButton` to make it support mutations274You can wrap your button component with `createMutationButton` to make it support mutations
275275
...@@ -312,7 +312,7 @@ It can now be used for easy mutations:...@@ -312,7 +312,7 @@ It can now be used for easy mutations:
312312
313313
314314
315### Batched Mutations315## Batched Mutations
316316
317Each call to the mutation applies new optimistic state on top of the previous,317Each call to the mutation applies new optimistic state on top of the previous,
318and after a debounce / throttle, the new optimistic state is committed to the318and after a debounce / throttle, the new optimistic state is committed to the
src/react.ts+8-10
...@@ -42,8 +42,7 @@ export type UseMutateResult<Args extends unknown[], Result> =...@@ -42,8 +42,7 @@ export type UseMutateResult<Args extends unknown[], Result> =
42export interface UseMutateResultBase<Args extends unknown[], Result> {42export interface UseMutateResultBase<Args extends unknown[], Result> {
43 run: (...args: Args) => void;43 run: (...args: Args) => void;
44 runWithOptions: (44 runWithOptions: (
45 options: RunOptions<Result>,45 ..._: [...args: Args, options: RunOptions<Result>]
46 ...args: Args
47 ) => Promise<Result>;46 ) => Promise<Result>;
48 clear: () => void;47 clear: () => void;
49}48}
...@@ -243,10 +242,13 @@ class Observer<Args extends unknown[], Result> {...@@ -243,10 +242,13 @@ class Observer<Args extends unknown[], Result> {
243 return promise;242 return promise;
244 }243 }
245244
246 runWithOptions(options: RunOptions<Result>, ...args: Args): void {245 runWithOptions(...array: [...args: Args, options: RunOptions<Result>]): void {
247 const mutation = this.mutation;246 const mutation = this.mutation;
248 if (!mutation) return;247 if (!mutation) return;
249248
249 const args = array.slice() as Args;
250 const options = args.pop() as RunOptions<Result>;
251
250 this.currentArgs = args;252 this.currentArgs = args;
251 const key = mutation.key(args);253 const key = mutation.key(args);
252254
...@@ -295,12 +297,8 @@ class Observer<Args extends unknown[], Result> {...@@ -295,12 +297,8 @@ class Observer<Args extends unknown[], Result> {
295 }297 }
296298
297 binding: UseMutateResult<Args, Result> = ((self: this) => ({299 binding: UseMutateResult<Args, Result> = ((self: this) => ({
298 run(...args) {300 run: self.run.bind(self),
299 return self.run(...args);301 runWithOptions: self.runWithOptions.bind(self),
300 },
301 runWithOptions(options, ...args) {
302 return self.runWithOptions(options, ...args);
303 },
304 clear() {302 clear() {
305 self.setState({303 self.setState({
306 status: ["error", "success"].includes(self.state.status)304 status: ["error", "success"].includes(self.state.status)
...@@ -459,8 +457,8 @@ function GenericMutationButton<...@@ -459,8 +457,8 @@ function GenericMutationButton<
459 const computedArgs = typeof args === "function" ? args(e) : args;457 const computedArgs = typeof args === "function" ? args(e) : args;
460 if (!computedArgs || e.defaultPrevented) return;458 if (!computedArgs || e.defaultPrevented) return;
461 state.runWithOptions(459 state.runWithOptions(
462 { onSuccess, onError, onSettled },
463 ...computedArgs,460 ...computedArgs,
461 { onSuccess, onError, onSettled },
464 );462 );
465 }, [state]),463 }, [state]),
466 isPending: state.isPending,464 isPending: state.isPending,