fix: make ES module hot reload reachable from the frontend#79
Merged
Conversation
Three gaps meant new module code shipped by solara never took effect without a manual page refresh: the Module model only imported code on initialize (no change:code listener), provideModule re-settled an already-settled promise (silent no-op) instead of overwriting the cache, and remapping an existing import-map entry threw, poisoning the registry with the error. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
hatch's env check calls a virtualenv API that no longer exists on the py3.8 toolchain the runner installs; the built wheel is version independent (test jobs still cover 3.7-3.11). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Newer hatch no longer installs the hook's own dependencies into its isolated build env, failing with 'Unknown build hook: jupyter-builder'. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
maartenbreddels
added a commit
to widgetti/solara
that referenced
this pull request
Jul 4, 2026
…eload (#1168) context.restart closes the per-kernel Module/ImportMap widgets, so the redefine path updated traits on dead widgets and new module code never reached the browser. create_modules/create_import_map now recreate closed widgets, define_module(Path) registers the bundle with the reloader (a vite/esbuild --watch rebuild triggers a normal reload), per-kernel bookkeeping is dropped on kernel close, and _modules mutation is locked against concurrent create_modules from other kernels. Also: one dead control comm (a closed page) no longer aborts reload for every other context (assert -> skip + per-context exception guard). The browser integration test needs the companion frontend fixes (widgetti/ipyreact#79) and is version-gated until they are released; unit tests cover the kernel side on current ipyreact. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
GitHub auto-fails workflows using the deprecated artifact actions, which made this workflow fail in seconds before doing anything. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
GitHub retired the ubuntu-20.04 runner image, so these jobs queued forever. 22.04 (not latest) because the test matrix still includes python 3.7, which setup-python only provides there. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Redefining a module (solara's
define_moduleupdate path sets.codeon the existing per-kernelModulewidget) never took effect in the browser without a manual page refresh. Three frontend gaps:change:codelistener — theModulemodel imported its code only ininitialize(); trait updates were ignored.provideModulere-settled an already-settled promise — a silent no-op, so even a second provide with new code never reached consumers. It now consumes the pending resolver and overwrites the cached promise.addModule's error path, poisoning the registry with the error. Now non-fatal (the module registry is the source of truth; only inter-module imports stay on the previous version until a page reload).change:codealso invalidates the registry entry synchronously, so consumers created after the update deterministically wait for the fresh import instead of racing the old promise.Test
Browser-based UI test (
tests/ui/module_hot_reload_test.py, runs in the existingpytest tests/ui/CI job): define a module, render a consumer, redefine the module with new code, render another consumer, assert the new version renders. Fails in 33s (timeout) on the previous frontend, passes in 2s with the fix.Found while building the analogous ES-module mechanism for ipyvue's vue3 branch (precompiled vite bundles for solara vue templates), where the full in-place hot-reload loop is verified end to end. Companion solara PR makes the kernel-side survive
context.restart(recreate closed Module/ImportMap widgets) and watchesdefine_module(Path)files.🤖 Generated with Claude Code