Commit 9360ed4
fix(target-react): transitively hoist deeply-indirected module-lets to useRef (Plan 04-04)
CI on 248f2cf went red: two React rete-flow VR tests (undo + reconnect)
failed deterministically — undo no-op'd, leaving the post-drag value in
place. Root cause was a latent emitter gap exposed by a663b0d's correct
live-read `$expose` rewrite.
`hoistModuleLet` lifts a module-scoped `let X = init` to a per-instance
`useRef` only when it is reachable from a lifecycle hook DIRECTLY or via a
SINGLE helper level (cases a/b). FlowCanvas's `historyStack`/`redoStack`
are reached only transitively ($onMount → event handler → pushHistory →
pushHistorySnapshot → stack), so they fell through to case (c) and stayed
as a per-render `let [] ` — reset to a fresh empty array every render.
While every consumer of the stacks was a first-render closure (handlers
bound once in $onMount; the old `$expose` handle captured at mount via `[]`
deps) the bug was dormant — they all shared render-0's array. The live-read
handle made the external `undo`/`redo` dispatch to the LATEST render's
closure, which read the freshly-emptied stack → undo had nothing to pop.
Fix: take the TRANSITIVE closure over the top-level helper call graph
(fixpoint, cycle-safe) and follow helper calls inside lifecycle/watcher
bodies, so a let reached through any depth of helper indirection hoists.
This is the deferred Plan 04-04 promotion.
Regenerating all 14 React leaves changes exactly four — the components with
the same deep-indirection pattern, all now correctly stabilised:
- rete/FlowCanvas: historyStack, redoStack (the reported regression)
- cropper/Cropper: cropReady round-trip guard
- data-table/DataTable: programmatic echo-guard, selectAllBox
- maplibre/Layer: ctx
Each was a per-render-reset guard that is now a stable useRef — latent bugs
of the same class, hardened.
Verified: 216/216 turbo test+typecheck tasks green; dist-parity unchanged;
the 2 previously-failing rete-flow tests + all 19 rete-flow React VR cells
pass locally. Test 3 in hoistModuleLet.test.ts flipped from asserting the
old conservative no-hoist to asserting the new transitive hoist.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent ed7dd32 commit 9360ed4
6 files changed
Lines changed: 156 additions & 159 deletions
File tree
- packages
- targets/react/src
- __tests__
- rewrite
- ui
- cropper/packages/react/src
- data-table/packages/react/src
- maplibre/packages/react/src
- rete/packages/react/src
Lines changed: 15 additions & 9 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
240 | 240 | | |
241 | 241 | | |
242 | 242 | | |
243 | | - | |
| 243 | + | |
244 | 244 | | |
245 | | - | |
246 | | - | |
247 | | - | |
248 | | - | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
249 | 251 | | |
250 | 252 | | |
251 | 253 | | |
| |||
279 | 281 | | |
280 | 282 | | |
281 | 283 | | |
282 | | - | |
283 | | - | |
284 | | - | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
285 | 288 | | |
286 | | - | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
287 | 293 | | |
288 | 294 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
6 | | - | |
7 | | - | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
| |||
16 | 17 | | |
17 | 18 | | |
18 | 19 | | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
25 | 32 | | |
26 | 33 | | |
27 | 34 | | |
| |||
201 | 208 | | |
202 | 209 | | |
203 | 210 | | |
204 | | - | |
205 | | - | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
206 | 215 | | |
207 | 216 | | |
208 | 217 | | |
| |||
226 | 235 | | |
227 | 236 | | |
228 | 237 | | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
229 | 241 | | |
230 | | - | |
231 | | - | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
232 | 283 | | |
233 | 284 | | |
234 | 285 | | |
| |||
247 | 298 | | |
248 | 299 | | |
249 | 300 | | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
250 | 311 | | |
251 | | - | |
| 312 | + | |
| 313 | + | |
252 | 314 | | |
253 | | - | |
254 | | - | |
| 315 | + | |
255 | 316 | | |
256 | 317 | | |
257 | 318 | | |
| |||
262 | 323 | | |
263 | 324 | | |
264 | 325 | | |
265 | | - | |
266 | | - | |
| 326 | + | |
267 | 327 | | |
268 | 328 | | |
269 | | - | |
270 | | - | |
271 | | - | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
272 | 333 | | |
273 | 334 | | |
274 | 335 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
| 112 | + | |
112 | 113 | | |
113 | 114 | | |
114 | 115 | | |
| |||
121 | 122 | | |
122 | 123 | | |
123 | 124 | | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
132 | | - | |
133 | | - | |
134 | | - | |
135 | | - | |
136 | | - | |
137 | | - | |
138 | | - | |
139 | | - | |
140 | 125 | | |
141 | 126 | | |
142 | 127 | | |
| |||
176 | 161 | | |
177 | 162 | | |
178 | 163 | | |
179 | | - | |
| 164 | + | |
180 | 165 | | |
181 | 166 | | |
182 | 167 | | |
| |||
194 | 179 | | |
195 | 180 | | |
196 | 181 | | |
197 | | - | |
| 182 | + | |
198 | 183 | | |
199 | 184 | | |
200 | 185 | | |
| |||
0 commit comments