Description
Describe the problem
I am releasing a significant Svelte component library for Foundry VTT. Foundry VTT is a virtual tabletop for role playing games with an open 3rd party developer API. A couple thousand developers are producing module / game system additions to Foundry and Svelte definitely has a place to bring a considerably better UI development experience. For Svelte to work well on this platform multiple independent compiled Svelte apps need to run on the same browser page.
The general problem is that presently there is a small conflict regarding styles / transitions in the Svelte internal runtime in ./src/runtime/internal/style_manager.ts
. Because the keys to store the generated styles / keyframe animation are not unique between runtimes one Svelte app can clobber the stored styles of another if both have transitioning components at the same time. The first runtime to finish all transitions wipes out all stored animation transitions for all runtimes / apps that have components transitioning at the time.
I think it is a big value add for multiple independent / compiled Svelte apps to be able to run on the same browser page. Again this is mostly a platform use case / scenario where many developers could be creating independent apps running at the same time which is the case with Foundry VTT.
Describe the proposed solution
I have made a proof of concept fix, but would like to discuss with the maintainers the appropriate course of action since this is my first potential commit to Svelte and this is a change to the internals. It is not a major change though and all tests pass and no new tests likely need to be written seemingly.
The ExtendedDoc interface needs to be updated for dynamic keys. I'm not a TS expert so in my proof of concept implementation I used the following which is not great, but this interface is not exported and is barely used in this source file:
interface ExtendedDoc extends Document {
[key: string]: any;
}
So the above is the first point of guidance I'd like to receive from the Svelte maintainers. This would be a great application for RegExp types, but that is not a thing for TS yet.
The next aspect is generating a unique ID. This only has to be defined once per runtime / app. For the PoC I appended Date.now()
. This "should" be OK, but a UUID would be better. I didn't see any sort of ID generating function in ./src/runtime/internal/utils.ts
, so guidance from the maintainers for suitable ID generation is great.
const uniqueId = Date.now();
const svelteStylesheet = `__svelte_stylesheet_${uniqueId}`;
const svelteRules = `__svelte_rules_${uniqueId}`;
Instead of accessing the stored styles like doc.__svelte_stylesheet
use the keys above and access like
doc[svelteStylesheet]
and doc[svelteRules
] in create_rule and clear_rules.
That's it.. This is IMHO a low impact / high reward change and allows multiple independently compiled Svelte apps to run on the same browser page without conflicts. I couldn't detect any other conflicts in my Svelte lib for Foundry VTT between multiple independent apps.
The full PoC is here, but I'll redo the fork / make a PR w/ discussion and guidance from the core maintainers resulting from the above. Pinging @tanhauhau as you were the last one to touch style_manager.ts
... Great tutorial vids BTW!
Also, I have a temporary repo here where I debugged things that goes through an exhaustive description with picts of the problem in the README.
Alternatives considered
There are no alternatives. This is a blocking issue for Svelte apps / multiple runtimes to function correctly on the same browser page. This is valuable for using Svelte for platform use cases where multiple developers release many packages / apps that can be installed simultaneously. While I label this as "blocking" it is not a crashing type scenario, but a problem nonetheless for quality.
Importance
blocking / not crashing / quality improvement