Skip to content

Derived is still not updating synchronously #15721

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mcous opened this issue Apr 9, 2025 · 1 comment · Fixed by #15724
Closed

Derived is still not updating synchronously #15721

mcous opened this issue Apr 9, 2025 · 1 comment · Fixed by #15724
Assignees

Comments

@mcous
Copy link

mcous commented Apr 9, 2025

Describe the bug

I believe this issue is a continuation of #15590. I was excited to see the fix for this issue, and immediately updated so I could remove some workarounds I had in place for my test suite. To my surprise, removing the workarounds caused the tests to fail.

I have JS module that takes a signal as input, feeds that signal into a mutable $derived internally, and exposes an onChange method to optimistically update the $derived. The module and tests look something like this:

export type AppStateOptions = Readonly<{
  source: () => string;
}>;

export interface AppState {
  value: string;
  onChange: (nextValue: string) => void;
}

export const createAppState = (
  options: AppStateOptions
): AppState => {
  const source = $derived(options.source());
  let value = $derived(source);

  const onChange = (nextValue: string) => {
    value = nextValue;
  };

  return {
    get value() {
      return value;
    },
    onChange,
  };
};
import { test, expect } from "vitest";

import * as Subject from "../app-state.svelte";

test("optimistically updates value", () => {
  const result = Subject.createAppState({ source: () => "wrong" });

  result.onChange("right");

  expect(result.value).toBe("right");
});

This test fails!

 FAIL  src/lib/__tests__/app-state.svelte.spec.ts > optimistically updates value
AssertionError: expected 'wrong' to be 'right' // Object.is equality

Expected: "right"
Received: "wrong"

Just like in #15590, if I read result.value before calling onChange. The test passes.

+ void result.value;
  result.onChange("right");

  expect(result.value).toBe("right");

Interestingly, removing the intermediate const source = $derived(options.source()) also fixes the issue:

- const source = $derived(options.source());
- let value = $derived(source);
+ let value = $derived(options.source());

At this point, this is mostly an annoyance in testing. Outside of this particular issue, though, we've been having persistent issues with $derived chains failing to update when expected. These issues have proved difficult to minimally reproduce, but I will file more issues if/when I'm able to boil them down

Reproduction

This was a bit tricky to reproduce in the REPL - it does not repro in the <script> tag of a component. I was, however, able to repro by placing the code in question inside a button's click handler:

https://svelte.dev/playground/c88b99a5f9574364a587e1211a0b230a?version=5.25.10#H4sIAAAAAAAAE3VSXYucQBD8K81woAtG390POHL5BYG8xMDNaq83d2PPMNN6BvG_h9lZvRU2T0pVdRVWOQmSHYpSvKBTAzZAhqHrWZ41ikxclEYvyt-T4L82yAIgsuXo2drcD6g5YGfp8RFeG2Ik9qIUhwiWxrIy5MH1hB6KU0UVHXztlOXwzqqzxjFMtUPJ-GztT5aMM1yc6SDJC2ntNx-gW0r-7pPgUXFtyDMYqrWqP-AI6Q6OJ5gCtZDXQzjC1jxNPp2hNtlFaVFAT7XpOiQGNnBR40oMRjXRJR-k7jESETD0_U1Si2niVPvGi11INhpzbdr09cdosWZsoBJXUSUyaA3D03RnOr9eT-eKDsVXM3Q498yGYLp94nxyPQGj50MRqZPIBOPIomTX45z9Z7oHFW43fCy4GxPH60ix1G2ZoXhFrKT-Fb7lawONDN70rg6Spyb-cxtpRQBBdS3hXhTPdvvQAsCyc2w75BGOvEkDgNVlJfcBn28mDrl3tGjbJTXdLdAqGdZbgDmLzyU8Wyzn_bb6P5lgqfSnokaUF6k9zv8A1r21IW8DAAA=

System Info

System:
    OS: macOS 14.3.1
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 575.77 MB / 32.00 GB
    Shell: 5.9 - /usr/local/bin/zsh
  Binaries:
    Node: 22.14.0 - /usr/local/bin/node
    npm: 10.9.2 - /usr/local/bin/npm
    pnpm: 9.15.5 - ~/.nvs/default/bin/pnpm
  Browsers:
    Chrome: 123.0.6312.86
    Safari: 17.3.1
  npmPackages:
    svelte: latest => 5.25.10

Severity

annoyance

@7nik
Copy link
Contributor

7nik commented Apr 9, 2025

It looks like the issue related to the unowned deriveds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants