change(web): import ordering, SearchSpace.inputSequence getter

This commit is contained in:
Joshua Horton 2025-08-12 08:41:15 -05:00
parent b544aeff37
commit 0598e080bd
3 changed files with 34 additions and 19 deletions

View file

@ -1,16 +1,17 @@
/*
* Keyman is copyright (C) SIL Global. MIT License.
*
*
* Created by jahorton on 2025-07-30
*
*
* Represents cached data about one token (either a word or a unit of whitespace)
* in the context and associated correction-search progress and results.
*/
import { buildMergedTransform } from "@keymanapp/models-templates";
import { SearchSpace } from "./distance-modeler.js";
import { KMWString } from "@keymanapp/web-utils";
import { buildMergedTransform } from "@keymanapp/models-templates";
import { LexicalModelTypes } from '@keymanapp/common-types';
import { SearchSpace } from "./distance-modeler.js";
import Distribution = LexicalModelTypes.Distribution;
import LexicalModel = LexicalModelTypes.LexicalModel;
import Suggestion = LexicalModelTypes.Suggestion;
@ -31,7 +32,7 @@ function textToCharTransforms(text: string, transformId?: number): Transform[] {
return transformId ?
[...text].map(insert => ({insert, deleteLeft: 0, id: transformId})) :
[...text].map(insert => ({insert, deleteLeft: 0}));
}
}
/**
* Represents cached data about one token (either a word or a unit of whitespace)

View file

@ -366,7 +366,7 @@ export class SearchSpace {
private tierOrdering: SearchSpaceTier[] = [];
private selectionQueue: PriorityQueue<SearchSpaceTier>;
inputSequence: Distribution<Transform>[] = [];
private _inputSequence: Distribution<Transform>[] = [];
private minInputCost: number[] = [];
private rootNode: SearchNode;
@ -397,7 +397,7 @@ export class SearchSpace {
this.buildQueueSpaceComparator();
if(arg1 instanceof SearchSpace) {
this.inputSequence = [].concat(arg1.inputSequence);
this._inputSequence = [].concat(arg1._inputSequence);
this.minInputCost = [].concat(arg1.minInputCost);
this.rootNode = arg1.rootNode;
this.completedPaths = [].concat(arg1.completedPaths);
@ -475,6 +475,13 @@ export class SearchSpace {
}
}
/**
* Retrieves the sequence of inputs
*/
public get inputSequence() {
return [...this._inputSequence];
}
increaseMaxEditDistance() {
this.tierOrdering.forEach(function(tier) { tier.increaseMaxEditDistance() });
}
@ -482,11 +489,11 @@ export class SearchSpace {
get correctionsEnabled() {
// When corrections are disabled, the Web engine will only provide individual Transforms
// for an input, not a distribution. No distributions means we shouldn't do corrections.
return !!this.inputSequence.find((distribution) => distribution.length > 1);
return !!this._inputSequence.find((distribution) => distribution.length > 1);
}
addInput(inputDistribution: Distribution<Transform>) {
this.inputSequence.push(inputDistribution);
this._inputSequence.push(inputDistribution);
// Assumes that `inputDistribution` is already sorted.
this.minInputCost.push(-Math.log(inputDistribution[0].p));
@ -607,9 +614,9 @@ export class SearchSpace {
let deletionEdges: SearchNode[] = [];
if(!substitutionsOnly) {
deletionEdges = currentNode.buildDeletionEdges(this.inputSequence[inputIndex-1]);
deletionEdges = currentNode.buildDeletionEdges(this._inputSequence[inputIndex-1]);
}
let substitutionEdges = currentNode.buildSubstitutionEdges(this.inputSequence[inputIndex-1]);
let substitutionEdges = currentNode.buildSubstitutionEdges(this._inputSequence[inputIndex-1]);
// Note: we're live-modifying the tier's cost here! The priority queue loses its guarantees as a result.
nextTier.correctionQueue.enqueueAll(deletionEdges.concat(substitutionEdges));

View file

@ -1,14 +1,21 @@
/*
* Keyman is copyright (C) SIL Global. MIT License.
*
* Created by jahorton on 2025-07-30
*
* This file contains low-level unit tests designed to validate the behavior
* of the ContextToken class.
*/
import { assert } from 'chai';
// Aliased due to JS keyword.
import { default as defaultBreaker } from '@keymanapp/models-wordbreakers';
import { jsonFixture } from '@keymanapp/common-test-resources/model-helpers.mjs';
import { ContextToken } from '#./correction/context-token.js';
import { ExecutionTimer } from '#./correction/execution-timer.js';
import * as models from '#./models/index.js';
import { default as defaultBreaker } from '@keymanapp/models-wordbreakers';
import { jsonFixture } from '@keymanapp/common-test-resources/model-helpers.mjs';
var TrieModel = models.TrieModel;
import { TrieModel } from '#./models/index.js';
var plainModel = new TrieModel(jsonFixture('models/tries/english-1000'),
{wordBreaker: defaultBreaker});