Skip to content

feat(web): add .codepointLength field for SearchQuotientNode types 🚂#15440

Merged
jahorton merged 4 commits intoepic/autocorrectfrom
feat/web/module-codepoint-length
Jan 29, 2026
Merged

feat(web): add .codepointLength field for SearchQuotientNode types 🚂#15440
jahorton merged 4 commits intoepic/autocorrectfrom
feat/web/module-codepoint-length

Conversation

@jahorton
Copy link
Copy Markdown
Contributor

@jahorton jahorton commented Jan 15, 2026

In order to move the implementation of .split operations onto the SearchQuotientNode types, its instances will need a way to recursively find the correct split point. .codepointLength, along with the helper .leftDeleteLength and .insertLength properties, will provide a clear and clean way to do exactly that.

Build-bot: skip build:web
Test-bot: skip

@github-project-automation github-project-automation Bot moved this to Todo in Keyman Jan 15, 2026
@keymanapp-test-bot keymanapp-test-bot Bot added the user-test-missing User tests have not yet been defined for the PR label Jan 15, 2026
@keymanapp-test-bot
Copy link
Copy Markdown

keymanapp-test-bot Bot commented Jan 15, 2026

User Test Results

Test specification and instructions

User tests are not required

Test Artifacts

  • Web
    • KeymanWeb Test Home - build : all tests passed (no artifacts on BuildLevel "build")

@github-actions github-actions Bot added the feat label Jan 15, 2026
@keymanapp-test-bot keymanapp-test-bot Bot changed the title feat(web): add .codepointLength field for SearchQuotientNode types feat(web): add .codepointLength field for SearchQuotientNode types 🚂 Jan 15, 2026
@keymanapp-test-bot keymanapp-test-bot Bot added this to the A19S20 milestone Jan 15, 2026
@jahorton jahorton force-pushed the refactor/web/rename-and-doc-pending-tokenization branch from 4c06d81 to 53ed374 Compare January 15, 2026 22:29
@jahorton jahorton force-pushed the feat/web/module-codepoint-length branch from 36f8441 to cf6643d Compare January 15, 2026 22:40
@keyman-server keyman-server modified the milestones: A19S20, A19S21 Jan 16, 2026
@jahorton jahorton force-pushed the refactor/web/rename-and-doc-pending-tokenization branch 3 times, most recently from db9f4ed to 92d0472 Compare January 22, 2026 19:06
@jahorton jahorton force-pushed the feat/web/module-codepoint-length branch from cf6643d to da23429 Compare January 22, 2026 19:11
@jahorton jahorton force-pushed the refactor/web/rename-and-doc-pending-tokenization branch from 92d0472 to cfe72f4 Compare January 22, 2026 19:26
@jahorton jahorton force-pushed the feat/web/module-codepoint-length branch from da23429 to 3149eab Compare January 22, 2026 19:27
@keymanapp-test-bot keymanapp-test-bot Bot removed the user-test-missing User tests have not yet been defined for the PR label Jan 28, 2026
@jahorton jahorton requested review from ermshiperete and mcdurdin and removed request for ermshiperete January 28, 2026 23:21
@jahorton jahorton marked this pull request as ready for review January 28, 2026 23:21

get codepointLength(): number {
if(this._codepointLength === undefined) {
this._codepointLength = this.parentNode.codepointLength + this.insertLength - this.leftDeleteLength;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we set this outside of get()?

Copy link
Copy Markdown
Contributor Author

@jahorton jahorton Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, so this gets a bit complicated because of the TS type system.

Note the .insertLength and .leftDeleteLength properties.

image

Those two properties cannot be set in the SearchQuotientSpur constructor and are thus unavailable for use in initializing the field during construction time. As a result, I opted to take a "lazy initialization" strategy - we'll calculate it once, when it's needed, and lock in the value at that time.

While it could be dynamically generated at runtime on each access, bypassing the need to set an instance field entirely, that'd make accesses an O(N) call each time on the length of the string, rather than O(1). (I'm aiming to optimize the number of KMWString calls, as the code involves lots of branches and loops, thus could suffer significant branch-prediction misses.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
this._codepointLength = this.parentNode.codepointLength + this.insertLength - this.leftDeleteLength;
// caching result for performance
// note that readonly abstract props cannot be accessed in constructor
this._codepointLength = this.parentNode.codepointLength + this.insertLength - this.leftDeleteLength;

But this does feel a little bit like working too hard for structural elegance (readonly abstract properties) and shooting yourself in the foot in the process because then you need this pattern. Another way of solving this could be by including the value or values as parameters to the SearchQuotientSpur constructor.


return {
text: KMWString.substring(bestPrefix.text, 0, KMWString.length(bestPrefix.text) - bestLocalInput.sample.deleteLeft) + bestLocalInput.sample.insert,
text: KMWString.substring(bestPrefix.text, 0, (this.parentNode?.codepointLength ?? 0) - bestLocalInput.sample.deleteLeft) + bestLocalInput.sample.insert,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For maintainability of what bestExample() is calculating, can we we split this change to a const above? (to a descriptive variable) along with some comments how it's "best".

Base automatically changed from refactor/web/rename-and-doc-pending-tokenization to epic/autocorrect January 29, 2026 15:27
@jahorton jahorton merged commit 6355771 into epic/autocorrect Jan 29, 2026
7 of 8 checks passed
@jahorton jahorton deleted the feat/web/module-codepoint-length branch January 29, 2026 16:05
@github-project-automation github-project-automation Bot moved this from Todo to Done in Keyman Jan 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

5 participants