refactor: drop the liveMode IORef, thread live explicitly - #1633
Merged
Conversation
Remove the global `liveMode :: IORef Bool` (a `NOINLINE` / `unsafePerformIO` top-level ref set once in `initComponent`) and pass the live-reload flag as an explicit `Bool` argument instead. The flag gates key-based model recovery in `initialize` — outside hot reload, a keyed component must never inherit a previous (possibly unrelated) component's model just because it shares a `Key`. ## Changes - **`initialize`**: takes a new `live :: Bool` parameter (documented with the recovery-gating rationale formerly on the IORef). The `readIORef liveMode` at the model-recovery check is replaced by the parameter. - **`buildVTree`**: gains the same parameter and threads it through both recursive child-building calls; its nested `buildComp` passes it to the recursive `initialize` for `VComp` / `VCompStatic` children — including keyed ones, where the flag actually matters. - **`initialDraw`**: gains the parameter and forwards it to both of its `buildVTree` calls (the initial draw and the hydration-failure redraw). - **`initComponent`**: passes its existing `live` argument straight into `initialize`; the `atomicWriteIORef liveMode live` is deleted. - **`componentListener`** (NATIVE / Lynx MTS): takes `live` as well, supplied at its registration site in `initComponent`, so MTS-mounted children — and their keyed descendants via `buildVTree` — observe the same value the IORef would have held. - **`liveMode`** definition, its `NOINLINE` pragma, and its doc comment are removed. The ref was not exported, so no module outside `Miso.Runtime` is affected. - Cosmetic: `initSubs` type signature reformatted to one argument per line. ## Verification - `cabal build miso` (project default `+template-haskell +native`, GHC 9.12.2): compiles cleanly, covering the `NATIVE` branch. - Non-native (web / SSR) flavor built via a temporary project file with only `+template-haskell`: compiles cleanly. No behavior change intended: every call site receives exactly the value the IORef would have contained at that point.
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
Removes the global
liveMode :: IORef Bool(aNOINLINE/unsafePerformIOtop-level ref set once ininitComponent) and passes the live-reload flag as an explicitBoolargument through the runtime instead.The flag gates key-based model recovery in
initialize— outside hot reload, a keyed component must never inherit a previous (possibly unrelated) component's model just because it shares aKey. That rationale now lives on the parameter's haddock instead of the IORef's.Changes (
src/Miso/Runtime.hs)initializetakes a newlive :: Boolparameter (afterisRoot); thereadIORef liveModeat the model-recovery check is replaced by the parameter.buildVTreegains the same parameter and threads it through both recursive child-building calls; its nestedbuildComppasses it to the recursiveinitializeforVComp/VCompStaticchildren — including keyed ones, where the flag actually matters.initialDrawgains the parameter and forwards it to both of itsbuildVTreecalls (initial draw and the hydration-failure redraw).initComponentpasses its existingliveargument straight intoinitialize; theatomicWriteIORef liveMode liveis deleted.componentListener(NATIVE / Lynx MTS) takesliveas well, supplied at its registration site ininitComponent, so MTS-mounted children — and their keyed descendants viabuildVTree— observe the same value the IORef would have held.liveModedefinition,NOINLINEpragma, and doc comment removed. The ref was not exported, so nothing outsideMiso.Runtimeis affected.initSubstype signature reformatted to one argument per line.Verification
cabal build misowith the project defaults (+template-haskell +native, GHC 9.12.2) compiles cleanly — covers theNATIVEbranch.+template-haskell, compiles cleanly as well.No behavior change intended: every call site receives exactly the value the IORef would have contained at that point.