Repository navigation
refactor(): route model calls through _invoke - #325
Merged
Merged
Conversation
Every call to a model's worker goes through FragmentsModel._invoke() instead of spelling out threads.invoke(model.modelId, …) at each of the 89 call sites. The model is now the one place that knows how its worker is addressed, which is what the typing of these calls and the internal uid build on. Mechanical, with one behavior detail: the calls to a delta model go through the delta model itself, looked up with _getDeltaModel(), instead of invoking its modelId. A deltaModelId whose model is no longer loaded now reads as "no edits" where it sent a request for a missing model. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 11, 2026
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.
Part of a stack of six PRs that replaces #305. The branches live in a fork, so GitHub can't chain them: every PR is based on
main, and the diff of each one includes the PRs below it. Each PR names the commits that are its own and links a comparison that shows only those. They are meant to merge in the order below, and PRs 2 to 6 stay drafts until the one before them is in.The work. All model state, on both threads, is keyed by the consumer's
modelId, and amodelIdcan be reused. Late async work of a model that was disposed or replaced (a worker reply, queued tiles, a material transfer, a progress event, an in-flight dispose) therefore lands on the next model loaded under the same ID. The stack gives each model an internal uid that is never reused and routes everything by it, addsload({ signal })(#173), and types the messages between the threads, where most of the bugs it fixes were hidden behindany.The stack, bottom to top, in merge order:
refactor(): route model calls through _invoke: mechanical groundwork, no behavior changefix(): type calls to a model's worker, rebuild what the worker copiesfeat(): load abort signal + harden the message layerfix(): key models by an internal uid, dispose synchronously: the core fixfix(edit): key editor state by the model's uidrefactor(): type the requests workers send to the main threadEvery commit in the stack type-checks and passes the test suite on its own, and each PR builds. The top of the stack matches #305's branch merged with today's
main, apart from one fix that merge needs (see PR 4) and two reworded lines.This PR's own diff: all of it. It is the bottom of the stack.
Description
PR 1 of 6. Every call to a model's worker-side counterpart now goes through
FragmentsModel._invoke(method, args)instead of spelling outmodel.threads.invoke(model.modelId, method, args)at each of the 89 call sites. The model becomes the one place that knows how its worker is addressed.Nothing else changes here. The PRs above build on it: PR 2 types
_invoke, and PR 4 switches what it addresses frommodelIdto uid in one line.It is mechanical: 14 files, +165/−309, no test changes, and the suite passes as it does on
main(143 tests).A prerequisite to #330 .
One behavior detail. The four calls
EditManagermakes to a model's delta model now go through the delta model itself, looked up with_getDeltaModel(), instead of invokingdeltaModelId. If that model is no longer inmodels.list, the call reads as "no edits". Before, the request was sent for a model that isn't loaded.Additional context
_invokedoesn't exist onmain. In #305 it arrived inside the uid commit, so none of the typing could merge ahead of it. This commit is new: it lifts those hunks out and routes bymodelIdfor now.Rebase next PRs
What is the purpose of this pull request?
Before submitting the PR, please make sure you do the following:
feat(examples): add hello-world example).fixes #123).🤖 Generated with Claude Code