Skip to content

refactor: word registry private to Words (T4) (@miodec) - #8567

Open
Miodec wants to merge 4 commits into
refactor/caret-boundaryfrom
refactor/word-registry-private
Open

Miodec wants to merge 4 commits into
refactor/caret-boundaryfrom
refactor/word-registry-private

Conversation

@Miodec

@Miodec Miodec commented Nov 11, 2026

Copy link
Copy Markdown
Member

Stacked on #8563 (T3): base is refactor/caret-boundary, retarget to master once that merges.

Summary

Roadmap T4: the word registry becomes private to Words. Only the overflow check stays exported.

 src/ts/
 ├── states/
-│   └── word-elements.ts        # module-level word + line break maps, LETTER_SELECTOR
 └── components/pages/test/
+    ├── word-registry.ts        # createWordRegistry(), one per Words
+    ├── selectors.ts            # LETTER_SELECTOR
     ├── Words.tsx               # creates the registry
     ├── Word.tsx                # registers through a `register` prop
     ├── words-layout.ts         # gets the registry as an option
     └── caret.ts                # no registry access
 <Words>
+  registry = createWordRegistry()
-  createWordsLayout({ words, wordsWrapper, caret, paceCaret })
+  createWordsLayout({ registry, words, wordsWrapper, caret, paceCaret })
-  <Word word isActive />                      // registerWordElement() global
+  <Word word isActive register={registry.registerWord} />
-  <LineBreak index />                         // registerLineBreakElements() global
+  <LineBreak index register={registry.registerLineBreak} />
 caret.goTo({
   wordIndex,
+  wordEl: registry.getWord(wordIndex),       // the layout passes the element
 })

wouldActiveWordOverflow (used by before-insert-text) reads the registry of the mounted Words, and returns true when none is mounted.

Evidence

  • Tests: all 107 files pass, including the test-page harness (27 tests). New word-registry.spec.ts covers the guard that keeps a remount's element when the old one's cleanup runs after it. words-wrapper-height.spec builds its own registry. The two Words.spec tests that read the global registry are gone; the existing rendered-output tests cover the same cases.
  • Browser (__mt.checkLayout()): [] after load, line jumps, tape mode (letter) with the pace caret on, and 25 extra letters. Caret offset 2–4px.
  • Overflow guard: at font size 6, typing 30 extra letters stopped at 21, with the word's top and height unchanged.

Merge Danger

Door: two-way

Internal refactor; reverting restores the global module.

Blast Radius: test-words

No visible change. The caret position, the line jump, the tape scroll and the extra-letter overflow block all read through the new registry, so a miss there shows up as a stuck caret or a wrapping word.

🤖 Generated with Claude Code

Miodec and others added 3 commits November 11, 2026 19:38
Words creates its own registry; Word and line breaks register through a
prop, the layout hands the caret the word element. Only the overflow check
is exported. LETTER_SELECTOR moves to the test page's selectors module.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@monkeytypegeorge monkeytypegeorge added frontend User interface or web stuff docs Related to Markdown files and documentation labels Nov 11, 2026
…admap

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Related to Markdown files and documentation frontend User interface or web stuff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants