Skip to content

feat(web): implement dedicated substitution-spur class, tests 🚂#15688

Open
jahorton wants to merge 6 commits into
epic/autocorrectfrom
feat/web/substitution-spurs
Open

feat(web): implement dedicated substitution-spur class, tests 🚂#15688
jahorton wants to merge 6 commits into
epic/autocorrectfrom
feat/web/substitution-spurs

Conversation

@jahorton
Copy link
Copy Markdown
Contributor

@jahorton jahorton commented Mar 5, 2026

This PR implements a strictly substitution-edit-edge variant of SearchQuotientSpur, which is one of the three specialized spur types needed to implement a proper "quotient graph" representation of the text-correction search space as documented at https://github.com/keymanapp/keyman/blob/8ac271788d56b04ee98a7a95d0191e6726220d52/web/src/engine/predictive-text/worker-thread/docs/correction-search-graph.md.

To contrast, the LegacyQuotientSpur type we've been using does all three at once, which makes it impossible to meet our needs for word-boundary correction processes. (Again, see the doc linked above.)

This PR also shifts many unit test fixtures from a LegacyQuotientSpur implementation to a SubstitutionQuotientSpur implementation, as the related tests were generally designed with only the substitution aspect in mind.

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

@keymanapp-test-bot
Copy link
Copy Markdown

keymanapp-test-bot Bot commented Mar 5, 2026

User Test Results

Test specification and instructions

User tests are not required

@keymanapp-test-bot keymanapp-test-bot Bot changed the title feat(web): implement dedicated substitution-spur class, tests feat(web): implement dedicated substitution-spur class, tests 🚂 Mar 5, 2026
@keymanapp-test-bot keymanapp-test-bot Bot added this to the A19S24 milestone Mar 5, 2026
@github-actions github-actions Bot added the feat label Mar 5, 2026
@jahorton jahorton force-pushed the feat/web/search-space-node-propagation branch from b0724e2 to c5f9b66 Compare March 9, 2026 21:24
@jahorton jahorton force-pushed the feat/web/substitution-spurs branch 3 times, most recently from 1183bcc to 360c0ae Compare March 9, 2026 21:47
@jahorton jahorton force-pushed the feat/web/search-space-node-propagation branch from c5f9b66 to 91cf42e Compare March 10, 2026 16:41
@jahorton jahorton force-pushed the feat/web/substitution-spurs branch 3 times, most recently from cfc8d96 to 816fac7 Compare March 11, 2026 14:55
@jahorton jahorton force-pushed the feat/web/search-space-node-propagation branch from 8800920 to c9b2859 Compare March 12, 2026 17:39
@jahorton jahorton force-pushed the feat/web/substitution-spurs branch from 816fac7 to adcb188 Compare March 12, 2026 17:40
@keyman-server keyman-server modified the milestones: A19S24, A19S25 Mar 14, 2026
@keyman-server keyman-server modified the milestones: A19S25, A19S26 Mar 28, 2026
@keyman-server keyman-server modified the milestones: A19S26, A19S27 Apr 14, 2026
@jahorton jahorton force-pushed the feat/web/search-space-node-propagation branch 3 times, most recently from b227e9e to d71345c Compare April 16, 2026 21:13
@jahorton jahorton force-pushed the feat/web/substitution-spurs branch from adcb188 to 7d2544f Compare April 16, 2026 21:31
@jahorton jahorton changed the base branch from feat/web/search-space-node-propagation to feat/web/quotient-node-finalizer April 20, 2026 16:04
@jahorton jahorton force-pushed the feat/web/substitution-spurs branch from 7d2544f to ed05f68 Compare April 20, 2026 16:07
@jahorton jahorton force-pushed the feat/web/quotient-node-finalizer branch 2 times, most recently from 18ef0a4 to 2a5f907 Compare April 22, 2026 18:45
Per the search quotient graph documentation, we should no longer have one node type handle all edit operation types.  Our current ("legacy") implementation and unit tests are most tailored for the needs of 'substitution' edit types, so this PR starts there.

Build-bot: skip build:web
Test-bot: skip
@jahorton jahorton force-pushed the feat/web/substitution-spurs branch from 2fd16c0 to 00f361b Compare April 22, 2026 20:03
@jahorton jahorton force-pushed the feat/web/substitution-spurs branch from 00f361b to 856466e Compare April 22, 2026 20:23
@jahorton jahorton force-pushed the feat/web/substitution-spurs branch 2 times, most recently from 086713a to 77b22a2 Compare April 23, 2026 13:56
@jahorton jahorton requested a review from ermshiperete April 24, 2026 14:31
@jahorton jahorton marked this pull request as ready for review April 24, 2026 14:31
@keyman-server keyman-server modified the milestones: A19S27, A19S28 Apr 24, 2026
Base automatically changed from feat/web/quotient-node-finalizer to epic/autocorrect May 5, 2026 19:53
Copy link
Copy Markdown
Contributor

@ermshiperete ermshiperete left a comment

Choose a reason for hiding this comment

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

LGTM

@@ -0,0 +1,32 @@
import { assert } from "chai";
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.

Header missing:

Suggested change
import { assert } from "chai";
/*
* Keyman is copyright (C) SIL Global. MIT License.
* /
import { assert } from "chai";

it('constructs paths properly', () => {
const {searchRoot, nodes} = buildQuotientDocFixture();

[searchRoot /*, nodes.sc1, nodes.sc2*/].forEach((n) => {
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.

Why do we have the commented nodes in these tests?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

See #15714 and #15720, which implement these nodes.

I first implemented the fixture and tests in #15720, then commented out the pieces not yet readied in the earlier PRs. They'll become un-commented in the other specialized-node PRs.

// const sc1 = new InsertionQuotientSpur(searchRoot);
// const sc2 = new InsertionQuotientSpur(sc1);

// // K1C0
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.

Do we have to keep the commented code?

@keyman-server keyman-server modified the milestones: A19S28, A19S29 May 11, 2026
@jahorton jahorton requested a review from ermshiperete May 20, 2026 14:36
@jahorton
Copy link
Copy Markdown
Contributor Author

Is this ready to go aside from the file header?

Ignore the failed unit test - it's fixed in the next PR - #15911.

@ermshiperete
Copy link
Copy Markdown
Contributor

ermshiperete commented May 21, 2026

Is this ready to go aside from the file header?

yep. LGTM.

Note the failed build/test though...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

3 participants