| author | |
| committer | |
| log | e3d6a4b906d60a10abef5cb9611947b52c979f1a |
| tree | 4a4ae27a2c0615f53649fa20b4079d18c781b904 |
| parent | 9fe44b404d1cfae5e4751ac3ef020ef8da521b1a |
| signature |
7 files changed, 25 insertions(+), 15 deletions(-)
jsr.json+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | { |
| 2 | 2 | "name": "@clo/react-mutation", |
| 3 | "version": "1.1.0", | |
| 3 | "version": "2.0.0", | |
| 4 | 4 | "exports": { |
| 5 | 5 | ".": "./src/mod.ts", |
| 6 | 6 | "./tanstack-query.ts": "./src/tanstack-query.ts", |
readme.changes.md+6| ... | ... | @@ -1,5 +1,11 @@ |
| 1 | 1 | # notable changes in React Mutation |
| 2 | 2 | |
| 3 | ## v2 | |
| 4 | ||
| 5 | ### breaking | |
| 6 | ||
| 7 | - rename `onSuccess` and `onSuccessDataOnly` to `onSuccessUi` and `onSuccessData`. | |
| 8 | ||
| 3 | 9 | ## v1.1 |
| 4 | 10 | |
| 5 | 11 | - Add `runAsHeadlessPromise`. The function name is intentionally long to avoid using it, please use `runWithOptions` instead. |
src/mutation.ts+7-7| ... | ... | @@ -273,13 +273,13 @@ export class BlockingMutation< |
| 273 | 273 | } |
| 274 | 274 | |
| 275 | 275 | const args = array.slice() as Args; |
| 276 | const { onSuccess, onSuccessDataOnly, onError, onSettled, onRestore } = args | |
| 276 | const { onSuccessUi: onSuccess, onSuccessData, onError, onSettled, onRestore } = args | |
| 277 | 277 | .pop() as RunOptions<Result>; |
| 278 | 278 | const promise = this.#runWithOptions(args, onRestore, true); |
| 279 | 279 | return promise.then((result) => { |
| 280 | 280 | // Call user handlers |
| 281 | 281 | onSuccess?.(result); |
| 282 | onSuccessDataOnly?.(result); | |
| 282 | onSuccessData?.(result); | |
| 283 | 283 | onSettled?.({ status: "success", result }); |
| 284 | 284 | return result; |
| 285 | 285 | }).catch((caught: unknown) => { |
| ... | ... | @@ -305,17 +305,17 @@ export class BlockingMutation< |
| 305 | 305 | } |
| 306 | 306 | |
| 307 | 307 | const args = array.slice() as Args; |
| 308 | const { onSuccess, onSuccessDataOnly, onError, onSettled, onRestore } = args | |
| 308 | const { onSuccessUi, onSuccessData, onError, onSettled, onRestore } = args | |
| 309 | 309 | .pop() as RunOptions<Result>; |
| 310 | const suppressAll = this.#options.debounceMs !== undefined && !onSuccess && !onError; | |
| 311 | const suppressGlobalSuccess = onSuccess !== undefined || suppressAll; | |
| 310 | const suppressAll = this.#options.debounceMs !== undefined && !onSuccessUi && !onError; | |
| 311 | const suppressGlobalSuccess = onSuccessUi !== undefined || suppressAll; | |
| 312 | 312 | const suppressGlobalError = onError !== undefined || suppressAll; |
| 313 | 313 | |
| 314 | 314 | const promise = this.#runWithOptions(args, onRestore, suppressAll); |
| 315 | 315 | promise.then((result) => { |
| 316 | 316 | // Call user handlers |
| 317 | onSuccess?.(result); | |
| 318 | onSuccessDataOnly?.(result); | |
| 317 | onSuccessUi?.(result); | |
| 318 | onSuccessData?.(result); | |
| 319 | 319 | onSettled?.({ status: "success", result }); |
| 320 | 320 | |
| 321 | 321 | // Call global handler unless suppressed |
src/react.ts+1-1| ... | ... | @@ -261,7 +261,7 @@ class Observer<Args extends unknown[], Result> { |
| 261 | 261 | const promise = mutation.runWithOptions( |
| 262 | 262 | ...args, |
| 263 | 263 | { |
| 264 | onSuccess: watchesSuccess ? () => {} : undefined, | |
| 264 | onSuccessUi: watchesSuccess ? () => {} : undefined, | |
| 265 | 265 | onError: watchesError ? () => {} : undefined, |
| 266 | 266 | // For debounced mutations, suppress global handlers in runWithOptions |
| 267 | 267 | // The debounce logic (#enqueueDebouncedCall) will call them once if needed |
src/types.ts+8-4| ... | ... | @@ -29,10 +29,14 @@ export interface Mutation<Args extends unknown[], Result> { |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 31 | export interface RunOptions<Result> { |
| 32 | /** Called on success, suppresses the global success handler */ | |
| 33 | onSuccess?: (result: Result) => void; | |
| 34 | /** Called on success, does NOT suppress the global success handler */ | |
| 35 | onSuccessDataOnly?: (result: Result) => void; | |
| 32 | /** Called to show the success UI. Passing this suppresses the global success handler. */ | |
| 33 | onSuccessUi?: (result: Result) => void; | |
| 34 | /** | |
| 35 | * Called with result data, but unlike `onSuccessUi`, this indicates the | |
| 36 | * caller is not concerned with the UI flow of the success. Passing this | |
| 37 | * does NOT suppress the global success handler. | |
| 38 | */ | |
| 39 | onSuccessData?: (result: Result) => void; | |
| 36 | 40 | /** Called on error, suppresses the global error handler */ |
| 37 | 41 | onError?: (error: unknown) => void; |
| 38 | 42 | /** Called on settled (doesn't suppress global handlers) */ |
test/ordering.test.ts+1-1| ... | ... | @@ -378,7 +378,7 @@ test("runWithOptions callbacks: onSuccess called before global handler", async ( |
| 378 | 378 | }); |
| 379 | 379 | |
| 380 | 380 | mutTest.runWithOptions({ |
| 381 | onSuccess: () => { | |
| 381 | onSuccessUi: () => { | |
| 382 | 382 | calls.push("onSuccess"); |
| 383 | 383 | }, |
| 384 | 384 | onSettled: () => { |
test/runWithOptions.test.tsx+1-1| ... | ... | @@ -32,7 +32,7 @@ test("runWithOptions should allow react hook to do local handling", async () => |
| 32 | 32 | <button |
| 33 | 33 | data-testid="a" |
| 34 | 34 | onClick={() => { |
| 35 | runWithOptions({ onSuccessDataOnly: () => {} }); | |
| 35 | runWithOptions({ onSuccessData: () => {} }); | |
| 36 | 36 | }} |
| 37 | 37 | > |
| 38 | 38 | button |