From 2f39b6a4fe105ba99110ed4a2b9b63124cccbfcc Mon Sep 17 00:00:00 2001 From: clover caruso Date: Thu, 12 Feb 2026 16:07:36 -0800 Subject: [PATCH] fix: pass context to optimistic handlers honestly really sus that ts didnt catch this bug. but i consider it a success that we had so many mutations at work that didn't requires directly accessing context in an optimistic updater -- it means the helpers pattern is too goated. --- jsr.json | 2 +- readme.changes.md | 6 ++++++ src/mutation.ts | 2 ++ test/optimistic.ts | 45 +++++++++++++++++++++++++++++++++++++++++++++ test/share.ts | 4 ++-- 5 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 test/optimistic.ts diff --git a/jsr.json b/jsr.json index f61edd0bbff8b9ed46023554385d2776b4f5dd83..780ea58c561668658f993415fcb3baa174ae3eed 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@clo/react-mutation", - "version": "2.0.0", + "version": "2.0.1", "exports": { ".": "./src/mod.ts", "./tanstack-query.ts": "./src/tanstack-query.ts", diff --git a/readme.changes.md b/readme.changes.md index 238c2556e6070a5d62519d821cd64bdc9f082947..6fa64248d6f3705c169b831042d0a8201689ff68 100644 --- a/readme.changes.md +++ b/readme.changes.md @@ -1,5 +1,11 @@ # notable changes in React Mutation +## v2.0.1 + +### bugfixes + +- typescript violation not passing client context to optimistic handlers + ## v2 ### breaking diff --git a/src/mutation.ts b/src/mutation.ts index 5093a65167227bd5a13a08f8af5ef9b14e17aee3..a89ffd42202576c0ea68803fa851826b2d7a8f66 100644 --- a/src/mutation.ts +++ b/src/mutation.ts @@ -413,6 +413,7 @@ export class BlockingMutation< try { this.#options.optimistic({ + ...this.#client.context, args, helpers: channel.helpers, onRestore, @@ -623,6 +624,7 @@ export class BlockingMutation< try { this.#options.optimistic({ + ...this.client.context, args, helpers: channel.helpers, onRestore, diff --git a/test/optimistic.ts b/test/optimistic.ts new file mode 100644 index 0000000000000000000000000000000000000000..ea3d33cf22e80fc60b0986c9af17a584c767aa00 --- /dev/null +++ b/test/optimistic.ts @@ -0,0 +1,45 @@ +import { delay } from "@clo/lib/async.ts"; +import { assertEquals } from "@std/assert"; +import { test, vi } from "vitest"; +import { createTestMutationClient } from "./share.ts"; + +test("passes context value to functions", async () => { + vi.useFakeTimers(); + const { client, successMessages } = createTestMutationClient(); + const calls: string[] = []; + + let values: number[] = []; + const mutTest = client.define({ + async mutate() { + values.push(this.contextValue); + calls.push("mutate"); + await delay(100); + }, + describe: ({ contextValue }) => { + values.push(contextValue); + calls.push("describe"); + return "test action"; + }, + describeResult: ({ contextValue }) => { + values.push(contextValue); + calls.push("describe"); + return "tested action"; + }, + optimistic: ({ contextValue, onRefetch, onRestore }) => { + values.push(contextValue); + onRefetch(async () => void calls.push("refetch")); + onRestore(async () => void calls.push("restore")); + calls.push("optimistic"); + }, + refetchOnSuccess: false, + }); + + mutTest.run(); + await vi.advanceTimersByTimeAsync(200); + + // Even with refetchOnSuccess=false, errors should still trigger refetch + assertEquals(calls.includes("refetch"), true, "refetch should be called on error"); + assertEquals(calls.includes("restore"), true, "restore should be called on error"); + assertEquals(successMessages.length, 1); + assertEquals(values, [42, 42, 42]); +}); diff --git a/test/share.ts b/test/share.ts index 834a5ccb446365a776609832b34e2ad7404eadce..ce209a1bce50dcd96d11d15ba0212158d59095a0 100644 --- a/test/share.ts +++ b/test/share.ts @@ -2,7 +2,7 @@ import { MutationClient } from "../src/client.ts"; export interface TestMutationClient { - client: MutationClient<{}, {}>; + client: MutationClient<{ contextValue: number }, {}>; errorMessages: Array<{ message: string; error: unknown }>; successMessages: string[]; } @@ -12,7 +12,7 @@ export function createTestMutationClient(): TestMutationClient { const successMessages: string[] = []; const client = new MutationClient({ - context: {}, + context: { contextValue: 42 }, getOptimisticHelpers: () => ({}), reportError: (message: string, error: unknown) => { errorMessages.push({ message, error }); -- 2.54.0