Skip to content

SvelteMap breaks $derived rune #15614

@tilyupo

Description

@tilyupo

Describe the bug

SvelteMap prevents $derived from caching the result when an unrelated key is updated. It requires very specific order of access and initialization. See playground reproduction for exact code.

Reproduction

Playground link

<script lang="ts">
	import {SvelteMap} from 'svelte/reactivity';

	const source = new SvelteMap<string, string>();

	let lastSeenSource: string | undefined = 'none';

	let id = $derived.by(() => {
		const result = source.get('some-random-key');
		if (lastSeenSource === result) {
			console.log("source didn't change, but derived.by called");
		}
		lastSeenSource = result;
		return result;
	});

	$effect(() => {
		let cancelled = false;
		function spin() {
			if (cancelled) return;

			id; // read derived value
			requestAnimationFrame(spin);
		}

                 // $derived works without Promise.resolve(), so it's required for the bug reproduction
		Promise.resolve().then(() => {
			spin();
		});

                 // trigger SvelteMap change
		const timeout = setTimeout(() => {
			source.set('unreleated-key', 'updated');
		}, 10);

		return () => {
			cancelled = true;
			clearTimeout(timeout);
		};
	});
</script>

Result: source didn't change, but derived.by called is logged every time id variable is accessed.
Expected result: id is cached and evaluated only once during initialization.

Logs

System Info

System:
    OS: macOS 14.7.2
    CPU: (10) arm64 Apple M2 Pro
    Memory: 110.47 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 22.14.0 - ~/.nvm/versions/node/v22.14.0/bin/node
    Yarn: 1.22.22 - ~/.nvm/versions/node/v18.16.0/bin/yarn
    npm: 10.9.2 - ~/.nvm/versions/node/v22.14.0/bin/npm
    pnpm: 10.6.5 - ~/.nvm/versions/node/v18.16.0/bin/pnpm
    bun: 1.1.43 - ~/.bun/bin/bun
  Browsers:
    Chrome: 134.0.6998.166
    Safari: 18.3.1

Severity

blocking an upgrade

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions