Closed typhonrt closed 1 year ago
I have created / tested a PR that exposes the ProxyComponent reload function on internal API at component.$$.hmr_reload
. It is rather useful to be able to reload Svelte components in a bespoke manner beyond just HMR use cases provided by svelte-hmr
. In this case I can utilize the PR changes to provide automatic reloading for a deployment platforms (FoundryVTT) i18n / localization changes that have an independent hook / event.
It would be great to discuss the use case for bespoke hot reloading beyond just HMR.
Given discussion on the Svelte Discord I got informed about the proxy.$$.hmr_cmp.$replace
way of replacing / reloading a proxy instance. This issue is resolved and associated PR is unnecessary. Thanks to Rixo / Dominik for the help and willingness to engage!
For those that this might help as of Svelte v3 here is how to replace / reload a ProxyComponent instance when running the Vite dev server w/ svelte-hmr
. This is my full / actual solution, so just take note of the appShell.$$.hmr_cmp
and $replace
section:
if (import.meta.hot)
{
Hooks.on('hotReload', (data) =>
{
// Only handle JSON hot reload presumably specified in package manifest for language translation files.
if (data?.extension === 'json')
{
// Postpone until next clock tick to allow Foundry to update localization first.
setTimeout(() =>
{
for (const app of TJSAppIndex.values())
{
const appShell = app.svelte.applicationShell;
// Retrieve the original `svelte-hmr` instrumented HMR component / not the proxy.
const hmrComponent = appShell?.$$?.hmr_cmp;
if (appShell && typeof hmrComponent?.$replace === 'function')
{
const svelteData = app.svelte.dataByComponent(appShell);
if (svelteData)
{
try
{
// Replace with self; this will invoke `on_hmr` callback in associated SvelteApplication.
hmrComponent.$replace(hmrComponent.constructor, {
target: svelteData.config.target,
anchor: svelteData.config.anchor,
preserveLocalState: true,
conservative: true
});
}
catch (error)
{
const name = hmrComponent?.constructor?.name ?? 'Unknown';
console.error(`TyphonJS Runtime Library error; Could not hot reload component: '${name}'`);
console.error(error);
}
}
}
}
}, 0);
}
return true;
});
}
Hi @rixo / @dominikg,
I'd like to find out if at all possible that the
reload
mechanism associated withProxyComponent
could be exposed on$$
/ internal API; perhaps name ithmr_reload
. A use case just presented itself for the platform that I deliver my Svelte UI framework on as things go. This is a TTRPG / VTT / Foundry VTT. They just enabled custom hot reloading for data files including localization / i18n. I can easily tap into the platforms hot reload callback and reload the mounted Svelte component with access to thereload
function that currently is only used forimport.meta.hot
internally tosvelte-hmr
otherwise it is not accessible.It should be noted that I simply expose the
reload
method on ProxyComponent for this proof of concept demo. Ideally it would be exposed on$$
though as internal API.Thanks for your work on this package. I can see bespoke hot reloading made possible with this one adjustment and I know all the devs using my UI framework would like to have hot reloading for language / i18n data changes.
Here is a video demoing hot reload for i18n by modifying a language / translation JSON file on Foundry + my Svelte UI framework:
https://user-images.githubusercontent.com/311473/227505519-f87a42fd-7163-4795-82b3-987dbca33775.mov