fix(runtime,main-thread): backport branch-independent fixes from vapor - #359
Draft
Huxpro wants to merge 1 commit into
Draft
fix(runtime,main-thread): backport branch-independent fixes from vapor#359Huxpro wants to merge 1 commit into
Huxpro wants to merge 1 commit into
Conversation
Ports the parts of the `vapor` line that are not vapor-specific, both because they are fixes `main` wants on its own terms and because it shrinks the eventual vapor -> main merge surface in shared files. - worklet-apply: INIT_MT_REF is an 'always' op during hydration, so the BG initial value is authoritative — it was being dropped whenever the MT first-screen render had already registered the same _wvid. Mutate the existing cell (worklet-runtime hands these out by reference) instead of skipping. resetWorkletState() was an empty stub; it now clears the external ref registry, and IFR teardown calls it for the same reason it clears list state — the replay re-applies SET_MT_REF / INIT_MT_REF. - ifr: a diverging list platform attribute (item-key, estimated sizes, …) reaches native through update-list-info at insert time, so patching the JS map cannot repair the row native already knows about — treat it as a rebuild. A throwing hydration patch now falls back to the background replay instead of escaping vuePatchUpdate into Lepus. - flush: on the IFR main thread a missing ops sink fell through to callLepusMethod, re-entering vuePatchUpdate as if the batch came from the background thread; drop it with a dev warning instead. Guard `lynx` with typeof (bare AMD identifier) and skip arming the ack fallback in realms without setTimeout. - cross-thread: runOnMainThread no longer stamps _execId into the background exec map when the module evaluates in the IFR main-thread realm. - worklet-loader: use the shared hasMainThreadDirective so the two thread bundles cannot disagree about which files carry worklets. Not ported: scope-class handling (Page.ts), ShadowElement id -> uid, the hydration-complete handshake, and the flush observability hook — all tied to vapor infrastructure. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CuaHSwJh1PvJHUcwrH95pi
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
Follow-up to #358. Ports the parts of the
vaporline that aren't vapor-specific — each is a fixmainwants on its own terms, and porting them shrinks the eventualvapor→mainmerge surface in shared files.Ported
worklet-apply.ts— the background thread'sMainThreadRefinit value was being dropped.INIT_MT_REFis an'always'op during hydration precisely because the background value is authoritative, butapplyInitMtRefskipped whenever the main-thread first-screen render had already registered the same_wvid. Now it mutates the existing cell (worklet-runtime hands these out by reference) instead of skipping.resetWorkletState()was an empty stub; it now clears the external ref registry, and IFR teardown calls it for the same reason it clears list state — the replay re-appliesSET_MT_REF/INIT_MT_REF.ifr.ts— list platform metadata and the no-throw boundary. A divergingitem-key/estimated-main-axis-size-px/ … reaches native throughupdate-list-infoat insert time, so patching our JS map cannot repair the row native was already told about; that now forces a rebuild rather than an in-place patch (this was the open question I flagged in #357). A throwing hydration patch falls back to the background replay instead of escapingvuePatchUpdateinto Lepus.flush.ts— main-thread ops could be posted as background ops. On the IFR main thread with no ops sink installed,doFlushfell through tocallLepusMethod('vuePatchUpdate'), re-entering the executor as if the batch had come from the background thread and desyncing the hydration stream. It now drops the batch with a dev warning. Also:typeof lynxguard before use (bare AMD identifier throwsReferenceErrorin plain node realms), and the ack fallback is only armed wheresetTimeoutexists.cross-thread.ts—runOnMainThreadno longer stamps_execIdinto the background exec map when the module evaluates in the IFR main-thread realm; that map is meaningless there and the entry is retained for the life of the page.worklet-loader.ts— use the sharedhasMainThreadDirectiverather than an inline substring check, so the two thread bundles cannot disagree about which files carry worklets. No behavior change onmaintoday (the helper is the same substring check); it removes a call-site divergence and picks up vapor's AST-based version for free when that lands.Deliberately not ported
Page.tsscope handling andtransition-shared.ts— composable scope classes and theShadowElement.id→uidrename, both vapor infrastructure.vueIfrHydrationCompletehandshake,completeIfrInitialRender,ifrInert/isIfrEnabled— need the vapor background entry and plugin pipeline.__VUE_LYNX_FLUSH_HOOK__observability — benchmark tooling, not a fix.entry-main.ts'sSystemInfoinit — vapor flips the precedence between an engine-provided global andlynx.SystemInfo; the two behaviors differ and neither is obviously right, so I leftmain's alone.Testing
pnpm --filter vue-lynx-testing-library test— 238 passed (4 new).mt-worklet-refs.test.ts(2 of 3 fail without theworklet-applychange) and a list platform-metadata rebuild case inifr-list.test.ts(fails without theifr.tschange).pnpm --filter vue-lynx buildclean; biome clean over the touched sources.flush.tsandcross-thread.tsguards are not covered by new tests — both are small guards on paths that need a real IFR bundle to exercise.Generated by Claude Code