layercake icon indicating copy to clipboard operation
layercake copied to clipboard

Migrate to Runes

Open saabi opened this issue 6 months ago • 6 comments

After attempting to port a working Svelte 3/LayerCake app (using npm i -S --force LayerCake) I got the error above (ERR_SVELTE_TOO_MANY_UPDATES).

To verify the bug wasn't on my side, I moved an arbitrary working LayerCake REPL example to the Svelte 5 Preview REPL and I get the same error:

playground:output:801 Uncaught Error: ERR_SVELTE_TOO_MANY_UPDATES: Maximum update depth exceeded. This can happen when a reactive block or effect repeatedly sets a new value. Svelte limits the number of nested updates to prevent infinite loops.
    at infinite_loop_guard (playground:output:801:10)
    at flush_queued_effects (playground:output:818:4)
    at process_microtask (playground:output:845:3)

Working REPL Example: https://svelte.dev/repl/ad32f9f301484d0cace82272126e9d09?version=3.46.2 Svelte 5 REPL Example (failing)

saabi avatar Dec 26 '23 23:12 saabi

Thanks for letting me know. I’m waiting for the full Svelte 5 release before figuring out what form LayerCake takes. Given that the library is a collection of stores and stores are no more, it will mean a significant rewrite.

mhkeller avatar Dec 27 '23 00:12 mhkeller

I may be able to help out with that... I do dataviz, performance and low level for a living. Check out https://github.com/nestauk/svizzle It doesn't use LayerCake (yet) but a port is planned.

It will have to wait for a new LayerCake release however.

saabi avatar Dec 29 '23 03:12 saabi

Great – thanks for the offer! The first approach I plan on trying will be to replace every store with a $state rune and then instead of derived stores, use $derived. I haven't seen any examples on how runes interact with contexts, though.

Slots are also deprecated so there will have to be some changes there, too. It looks like the existing syntax may work if layout components render a children snippet.

But since Svelte 5 is still a moving target, I think it's better to wait until it settles.

mhkeller avatar Dec 29 '23 16:12 mhkeller

There's a PR for making this compatible with Svelte 5. I may merge it or may wait until 5.0.0 is out: https://github.com/mhkeller/layercake/pull/190

edit: this has been merged and the library is compatible with Svelte 5

mhkeller avatar May 03 '24 19:05 mhkeller

FYI the existing LayerCake library works out of the box in Svelte 5 projects. That PR clears up some peerDependency warnings.

Eventually I will port LayerCake to using runes but it will require changes to component API. Using $state runes, you can no longer destructure values from contexts like you can with stores

import { getContext } from 'svelte';
const { xGet, yGet } = getContext('LayerCake');

// becomes...

const chart = getContext('LayerCake')
chart.xGet
chart.yGet

I may include a helper so you're not interacting with getContext directly

import { LayerCake, Svg, getChart } from 'layercake';

const c = getChart();

c.xGet
c.YGet

The design is still TBD but that approach seems to help with the ergonomics. Feedback welcome.

mhkeller avatar May 03 '24 19:05 mhkeller

A note on the timing for this: Since the library is compatible with Svelte 4 and 5 but a migration to runes will cut off support for anything less than Svelte 5, I'm not in a huge rush to do that. It may make most sense to wait for something like Svelte 6 when some of the features Layer Cake uses become deprecated.

The goal here being that it works for the largest number of people.

mhkeller avatar May 09 '24 18:05 mhkeller