| author | |
| committer | |
| log | 2f39b6a4fe105ba99110ed4a2b9b63124cccbfcc |
| tree | 9665344e6da0a3a798e96f2a10f3ee51534dce9c |
| parent | e3d6a4b906d60a10abef5cb9611947b52c979f1a |
| signature |
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.5 files changed, 56 insertions(+), 3 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": "2.0.0", | 3 | "version": "2.0.1", |
| 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", |
readme.changes.md+6| ... | @@ -1,5 +1,11 @@ | ... | @@ -1,5 +1,11 @@ |
| 1 | # notable changes in React Mutation | 1 | # notable changes in React Mutation |
| 2 | 2 | ||
| 3 | ## v2.0.1 | ||
| 4 | |||
| 5 | ### bugfixes | ||
| 6 | |||
| 7 | - typescript violation not passing client context to optimistic handlers | ||
| 8 | |||
| 3 | ## v2 | 9 | ## v2 |
| 4 | 10 | ||
| 5 | ### breaking | 11 | ### breaking |
src/mutation.ts+2| ... | @@ -413,6 +413,7 @@ export class BlockingMutation< | ... | @@ -413,6 +413,7 @@ export class BlockingMutation< |
| 413 | 413 | ||
| 414 | try { | 414 | try { |
| 415 | this.#options.optimistic({ | 415 | this.#options.optimistic({ |
| 416 | ...this.#client.context, | ||
| 416 | args, | 417 | args, |
| 417 | helpers: channel.helpers, | 418 | helpers: channel.helpers, |
| 418 | onRestore, | 419 | onRestore, |
| ... | @@ -623,6 +624,7 @@ export class BlockingMutation< | ... | @@ -623,6 +624,7 @@ export class BlockingMutation< |
| 623 | 624 | ||
| 624 | try { | 625 | try { |
| 625 | this.#options.optimistic({ | 626 | this.#options.optimistic({ |
| 627 | ...this.client.context, | ||
| 626 | args, | 628 | args, |
| 627 | helpers: channel.helpers, | 629 | helpers: channel.helpers, |
| 628 | onRestore, | 630 | onRestore, |
test/optimistic.ts created+45| ... | @@ -0,0 +1,45 @@ | ||
| 1 | import { delay } from "@clo/lib/async.ts"; | ||
| 2 | import { assertEquals } from "@std/assert"; | ||
| 3 | import { test, vi } from "vitest"; | ||
| 4 | import { createTestMutationClient } from "./share.ts"; | ||
| 5 | |||
| 6 | test("passes context value to functions", async () => { | ||
| 7 | vi.useFakeTimers(); | ||
| 8 | const { client, successMessages } = createTestMutationClient(); | ||
| 9 | const calls: string[] = []; | ||
| 10 | |||
| 11 | let values: number[] = []; | ||
| 12 | const mutTest = client.define({ | ||
| 13 | async mutate() { | ||
| 14 | values.push(this.contextValue); | ||
| 15 | calls.push("mutate"); | ||
| 16 | await delay(100); | ||
| 17 | }, | ||
| 18 | describe: ({ contextValue }) => { | ||
| 19 | values.push(contextValue); | ||
| 20 | calls.push("describe"); | ||
| 21 | return "test action"; | ||
| 22 | }, | ||
| 23 | describeResult: ({ contextValue }) => { | ||
| 24 | values.push(contextValue); | ||
| 25 | calls.push("describe"); | ||
| 26 | return "tested action"; | ||
| 27 | }, | ||
| 28 | optimistic: ({ contextValue, onRefetch, onRestore }) => { | ||
| 29 | values.push(contextValue); | ||
| 30 | onRefetch(async () => void calls.push("refetch")); | ||
| 31 | onRestore(async () => void calls.push("restore")); | ||
| 32 | calls.push("optimistic"); | ||
| 33 | }, | ||
| 34 | refetchOnSuccess: false, | ||
| 35 | }); | ||
| 36 | |||
| 37 | mutTest.run(); | ||
| 38 | await vi.advanceTimersByTimeAsync(200); | ||
| 39 | |||
| 40 | // Even with refetchOnSuccess=false, errors should still trigger refetch | ||
| 41 | assertEquals(calls.includes("refetch"), true, "refetch should be called on error"); | ||
| 42 | assertEquals(calls.includes("restore"), true, "restore should be called on error"); | ||
| 43 | assertEquals(successMessages.length, 1); | ||
| 44 | assertEquals(values, [42, 42, 42]); | ||
| 45 | }); | ||
test/share.ts+2-2| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | import { MutationClient } from "../src/client.ts"; | 2 | import { MutationClient } from "../src/client.ts"; |
| 3 | 3 | ||
| 4 | export interface TestMutationClient { | 4 | export interface TestMutationClient { |
| 5 | client: MutationClient<{}, {}>; | 5 | client: MutationClient<{ contextValue: number }, {}>; |
| 6 | errorMessages: Array<{ message: string; error: unknown }>; | 6 | errorMessages: Array<{ message: string; error: unknown }>; |
| 7 | successMessages: string[]; | 7 | successMessages: string[]; |
| 8 | } | 8 | } |
| ... | @@ -12,7 +12,7 @@ export function createTestMutationClient(): TestMutationClient { | ... | @@ -12,7 +12,7 @@ export function createTestMutationClient(): TestMutationClient { |
| 12 | const successMessages: string[] = []; | 12 | const successMessages: string[] = []; |
| 13 | 13 | ||
| 14 | const client = new MutationClient({ | 14 | const client = new MutationClient({ |
| 15 | context: {}, | 15 | context: { contextValue: 42 }, |
| 16 | getOptimisticHelpers: () => ({}), | 16 | getOptimisticHelpers: () => ({}), |
| 17 | reportError: (message: string, error: unknown) => { | 17 | reportError: (message: string, error: unknown) => { |
| 18 | errorMessages.push({ message, error }); | 18 | errorMessages.push({ message, error }); |