authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-01-28 17:35:45-08:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-01-28 18:51:56-08:00
log2486cbb9d095be3d97251f02f076d0e2a1cb0033
tree07dc76904411d15ae8b97c3c862fb3b074afcd24
parentc6028dcd497631ff2d5a5a6c24b74b41f3ad21f4
signaturelock-open Commit is signed but in an unrecognized format.

fix: bring back the success message


5 files changed, 22 insertions(+), 13 deletions(-)

jsr.json+1-1
......@@ -1,6 +1,6 @@
11{
22 "name": "@clo/react-mutation",
3 "version": "1.0.0-beta.3",
3 "version": "1.0.0-beta.4",
44 "exports": {
55 ".": "./src/mod.ts",
66 "./tanstack-query.ts": "./src/tanstack-query.ts",
readme.md+3-3
......@@ -14,7 +14,7 @@ The primary gains React Mutation provides are
1414 `isError`, unhandled errors will be propagated to a global handler, which can
1515 display a UI toast. Otherwise, the component can display the error locally.
1616- Optimistic helpers allow defining rollbacks and refetching logic independant
17 of the actual mutation. The [built in helpers for React Query](#React-Query-Optimistic-Helpers) show this power in more detail.
17 of the actual mutation. The [built in helpers for React Query](#react-query-optimistic-helpers) show this power in more detail.
1818- Debounced Mutations are just so awesome to use.
1919
2020## Usage
......@@ -22,11 +22,11 @@ The primary gains React Mutation provides are
2222This library declares two kinds of mutations. Each kind has different behavior
2323around concurrent operations.
2424
25- [**Blocking Mutations**](#Blocking-Mutations): A mutation blocks the UI until it
25- [**Blocking Mutations**](#blocking-mutations): A mutation blocks the UI until it
2626 is complete. You press a button, a pending state appears, then it completes.
2727 This works great for forms, creations and deletions, and is similar to React
2828 Query's mutation system.
29- [**Debounced Mutations**](#Debounced-Mutations): Each call to the mutation applies
29- [**Debounced Mutations**](#debounced-mutations): Each call to the mutation applies
3030 new optimistic state, and after a debounce (or throttle) the new optimistic
3131 state is committed to the API. UI never shows a pending state for these.
3232 This works great for auto-saving input fields, follow buttons, and is
src/blocking.ts+3-2
......@@ -34,7 +34,7 @@ export interface BlockingMutationOptions<
3434 * Used in success messages.
3535 * Phrase it as a complete success message, e.g., "Deleted item successfully"
3636 */
37 describeResult: string | ((context: Config["context"] & { args: Args; result: Result }) => string);
37 describeResult: string | ((context: Config["context"] & { args: Args; result: Result }) => string) | null;
3838 /**
3939 * Specifying the optimistic strategy is required. To disable, pass an empty
4040 * function with a comment to document why it isn't needed.
......@@ -169,8 +169,9 @@ export class BlockingMutation<
169169 : describe;
170170 }
171171
172 describeResult(args: Args, result: Result): string {
172 describeResult(args: Args, result: Result): string | undefined {
173173 const { describeResult } = this.#options;
174 if (describeResult === null) return undefined;
174175 return typeof describeResult === "function"
175176 ? describeResult({ ...this.#client.context, args, result })
176177 : describeResult;
src/debounced.ts+14-6
......@@ -14,7 +14,10 @@ export interface DebouncedMutationOptions<
1414 * A rest params type is used to allow type inference. Place this function first to
1515 * ensure TypeScript correctly infers the argument type for the rest of the functions.
1616 */
17 optimistic: (context: DebouncedOptimisticContext<Config>, ...args: Args) => void;
17 optimistic: (
18 context: DebouncedOptimisticContext<Config>,
19 ...args: Args
20 ) => void;
1821 /**
1922 * Retrieve the current/optimistic value of the mutation. When this returns
2023 * the same thing as when the mutation started, it means that `mutate` does
......@@ -56,7 +59,7 @@ export interface DebouncedMutationOptions<
5659 ) => string);
5760 /**
5861 * Used in success messages.
59 * Phrase it as a complete success message, e.g., "Renamed item successfully"
62 * Phrase it as a complete success message: "Renamed item successfully"
6063 */
6164 describeResult:
6265 | string
......@@ -64,7 +67,8 @@ export interface DebouncedMutationOptions<
6467 context: DebouncedCommitContext<NoInfer<Args>, Optimistic, Config> & {
6568 result: Result;
6669 },
67 ) => string);
70 ) => string)
71 | null;
6872 /**
6973 * Refetch all of the data this mutation could have affected.
7074 */
......@@ -251,15 +255,16 @@ export class DebouncedMutation<
251255 }
252256
253257 // Not available for debounced mutations - success reporting happens during commit
254 describeResult: undefined = undefined;
258 describeResult: null = null;
255259
256260 #describeResult(
257261 args: Args,
258262 initial: Optimistic,
259263 current: Optimistic,
260264 result: Result,
261 ): string {
265 ): string | undefined {
262266 const { describeResult } = this.#options;
267 if (describeResult === null) return undefined;
263268 return typeof describeResult === "function"
264269 ? describeResult({
265270 ...this.#client.context,
......@@ -302,7 +307,10 @@ export class DebouncedMutation<
302307
303308 // If this is the first call in the debounced run, take a snapshot and create shared helpers
304309 if (channel.initial === null) {
305 channel.initial = this.#options.getValue({ ...this.#client.context, args });
310 channel.initial = this.#options.getValue({
311 ...this.#client.context,
312 args,
313 });
306314 channel.firstArgs = args;
307315
308316 // Create shared onRefetch handler for the debounced run
src/types.ts+1-1
......@@ -14,7 +14,7 @@ export interface Mutation<Args extends unknown[], Result> {
1414 cb: (update: MutationEvent<Result>) => void,
1515 ): () => void;
1616 describe(...args: Args): string;
17 describeResult?: (args: Args, result: Result) => string | undefined;
17 describeResult: ((args: Args, result: Result) => string | undefined) | null;
1818 client: MutationClient<object, object>;
1919}
2020