Skip to content
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

A way to display data from external libraries reactively #15068

Closed
eulertour opened this issue Jan 20, 2025 · 12 comments
Closed

A way to display data from external libraries reactively #15068

eulertour opened this issue Jan 20, 2025 · 12 comments

Comments

@eulertour
Copy link

Describe the problem

I have an AnimationController object which lets me pause, play, and seek through a canvas animation. The controller stores its data internally, but I want to display some of it reactively like the elapsed time and play/pause state in svelte.

I'm hoping to build an online editor which can display the attributes of any animated entity reactively so only a generalized solution is feasible. How can I handle this in svelte 5?

I've seen similar (the same?) issues that don't seem to have reached a consensus #10560, #11846, #14520, but I'm not asserting that svelte should handle this, only asking whether it can.

playground: https://svelte.dev/playground/a7b1bf2fb4d947eda4f72ebabd8b06e6?version=5.19.0

Describe the proposed solution

It'd be nice if there were a way to communicate to svelte that some attribute of a non-reactive library should be made reactive, e.g.

<script>
import AnimationController from "./AnimationController.js";
const animationController = new AnimationController();
</script>

<span>{$reactive(animationController.elapsedTime)}</span>

Importance

i cannot use svelte without it

@webJose
Copy link
Contributor

webJose commented Jan 20, 2025

Just to be clear:

REPL

You can make whatever data you need reactive, as shown in the modified REPL.

But the title says "external libraries", so I imagine your REPL was simply exemplary in nature.

The answer to your question is: You cannot do what the library doesn't provide. For example, the reactive MediaQuery class provided by Svelte exists because the underlying native media query in browsers provide the ability to register a callback that is executed whenever the query's value changes.

@eulertour
Copy link
Author

eulertour commented Jan 20, 2025

Yes as the issue title and the comment on the REPL say, my actual use case is using an external library.
It looks like there isn't a clean solution to this, but is there any solution that doesn't require modifying the library?

@webJose
Copy link
Contributor

webJose commented Jan 20, 2025

I don't think there is. The only way to detect change on an impenetrable black box is to look at it periodically, meaning polling. But I wouldn't do polling myself.

@eulertour
Copy link
Author

It's too bad that svelte can't handle this, but in case a solution is ever considered: the data itself is no less impenetrable (from the end-user perspective; I don't know how svelte handles its reactivity internally) than any other data svelte uses reactively:

<script>
  // svelte has to be explicitly told to make this reactive
  let elapsed = $state(0);

  const controller = new Controller();
  // The end user can tell svelte to make this reactive just the same
  let reactiveRef = $magic(controller.elapsed);
</script>

<span>{elapsed}</span>
<span>{reactiveRef}</span>

@webJose
Copy link
Contributor

webJose commented Jan 21, 2025

Not just Svelte. Not Vue, not React, Angular or SolidJS could handle this, just to randomly name a few. I may not have been clear: This cannot be done. It is not a matter of considering to solve it. It cannot be solved under the current state of things (browser API). If it is "impenetrable", no framework or library will ever be able to solve this, regardless of willingness.

First, a viable "backdoor" must appear before attempting anything.

@Conduitry
Copy link
Member

$state() is a directive tells the compiler that it should emit code to wrap the value in the appropriate proxies and that it should interact with the variable appropriately as a signal. There's nothing $magic() that could happen while leaving the underlying code unchanged. Subscribing to the issues you linked to is probably your best bet.

@eulertour
Copy link
Author

Does mean then that these issues are unsolvable? #10560, #11846

@eulertour
Copy link
Author

In case someone else comes across this issue, this is the solution I landed on. Miraculously, it doesn't require modifying the underlying library.

The dismissiveness and hostility from the maintainers in addressing this certainly hurts my confidence in svelte. Despite that I'll still say: the discord community is much more accommodating to questions like these and I haven't seen responses like this one from the people there.

@webJose
Copy link
Contributor

webJose commented Jan 21, 2025

You confuse assertive statements with hostility.

You see, the solution you have come up with, is what I told you to: An event listener that triggers an event can be used to build reactivity, just like MediaQuery does. The thing is: This is not THE solution to this or the related issues. This is a specific solution for the specific class you have used in your example, where you can derive from the original class and raising events whenever and wherever is appropriate.

Doing this requires knowledge of the internals of the original class. The example that stands out is that you know that the draw() method advances the animation.

Generally speaking what you have done cannot be extrapolated to a general solution. All this special knowledge cannot be automatically inferred.

@webJose
Copy link
Contributor

webJose commented Jan 21, 2025

Or maybe one day we can add AI to the Svelte framework to attempt this kind of thing? Who knows! That would be interesting.

@eulertour
Copy link
Author

I stated my question clearly. You said it was impossible.

Maybe you misread "doesn't require modifying the library" as "doesn't require knowledge of the library". Either way, it was an entirely dishonest and unprofessional response.

@webJose
Copy link
Contributor

webJose commented Jan 21, 2025

It is impossible to satisfy the issue you raised: To provide a general mechanism of making the properties of class instances reactive. That remains the case.

BTW, in case you took offense on my words alone: I'm not a Svelte maintainer. I'm some random guy that likes Svelte. That's it. It might be worth clarifying this fact.

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

No branches or pull requests

3 participants