Skip to content

Commit

Permalink
refactor(common): move all lexical model types into `LexicalModelType…
Browse files Browse the repository at this point in the history
…s` container

Many of the types had very generic names (e.g. `Configuration`), and as
the types are now exported from `@keymanapp/common-types`, this was
unhelpful.

For units with many references, I used TypeScript's import-equals to
reduce the change impact. For units with only a few references, I added
the `LexicalModelTypes.` prefix to the references in source.

(Best reference I could find for import-equals: evanw/esbuild@b722fa4)

Fixes: #12516
  • Loading branch information
mcdurdin committed Nov 27, 2024
1 parent 8be5907 commit b10634e
Show file tree
Hide file tree
Showing 35 changed files with 180 additions and 72 deletions.
2 changes: 1 addition & 1 deletion common/web/types/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ export { UnicodeSetParser, UnicodeSet } from './ldml-keyboard/unicodeset-parser-
export { VariableParser, MarkerParser } from './ldml-keyboard/pattern-parser.js';
export { ElementString } from './kmx/kmx-plus/element-string.js';

export { USVString, CasingForm, CasingFunction, TextWithProbability, LexiconTraversal, LexicalModel, LexicalModelPunctuation, Transform, Suggestion, Reversion, Keep, SuggestionTag, Context, Distribution, Outcome, WithOutcome, ProbabilityMass, Configuration, Capabilities, WordBreakingFunction, Span } from './lexical-model-types.js';
export * as LexicalModelTypes from './lexical-model-types.js';

export * as KeymanWebKeyboard from './keyboard-object.js';
4 changes: 3 additions & 1 deletion developer/src/kmc-model/src/join-word-breaker-decorator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Span, WordBreakingFunction } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';
import Span = LexicalModelTypes.Span;
import WordBreakingFunction = LexicalModelTypes.WordBreakingFunction;

/**
* Returns a word breaker that joins spans of an existing word breaker.
Expand Down
5 changes: 4 additions & 1 deletion developer/src/kmc-model/src/lexical-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
* the LMLayer's internal worker code, so we provide those definitions too.
*/

import { CasingFunction, LexicalModelPunctuation, WordBreakingFunction } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';
import CasingFunction = LexicalModelTypes.CasingFunction;
import LexicalModelPunctuation = LexicalModelTypes.LexicalModelPunctuation;
import WordBreakingFunction = LexicalModelTypes.WordBreakingFunction;

export interface LexicalModelDeclaration {
readonly format: 'trie-1.0'|'fst-foma-1.0'|'custom-1.0',
Expand Down
4 changes: 3 additions & 1 deletion developer/src/kmc-model/src/model-defaults.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { CasingForm, CasingFunction } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';
import CasingForm = LexicalModelTypes.CasingForm;
import CasingFunction = LexicalModelTypes.CasingFunction;

/**
* Converts wordforms into an indexable form. It does this by
Expand Down
4 changes: 3 additions & 1 deletion developer/src/kmc-model/src/model-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import { defaultApplyCasing,

import KEYMAN_VERSION from "@keymanapp/keyman-version";
import { LexicalModelSource, WordformToKeySpec } from "./lexical-model.js";
import { CasingForm, CasingFunction } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';
import CasingForm = LexicalModelTypes.CasingForm;
import CasingFunction = LexicalModelTypes.CasingFunction;

/**
* Processes certain defined model behaviors in such a way that the needed closures
Expand Down
4 changes: 3 additions & 1 deletion developer/src/kmc-model/src/script-overrides-decorator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Span, WordBreakingFunction } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';
import Span = LexicalModelTypes.Span;
import WordBreakingFunction = LexicalModelTypes.WordBreakingFunction;
import { OverrideScriptDefaults } from "./lexical-model.js";
import { ModelCompilerError, ModelCompilerMessages } from "./model-compiler-messages.js";

Expand Down
4 changes: 2 additions & 2 deletions web/src/app/webview/src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { EngineConfiguration, InitOptionSpec, InitOptionDefaults } from "keyman/
import { buildMergedTransform } from '@keymanapp/models-templates';

import { type OnInsertTextFunc } from "./contextManager.js";
import { Transform } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';

export class WebviewConfiguration extends EngineConfiguration {
private _embeddingApp: string;
private _oninserttext: OnInsertTextFunc;
private _hostInsert: OnInsertTextFunc;

private pendingInserts: Transform[] = [];
private pendingInserts: LexicalModelTypes.Transform[] = [];

initialize(options: Required<WebviewInitOptionSpec>) {
super.initialize(options);
Expand Down
4 changes: 2 additions & 2 deletions web/src/app/webview/src/contextManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Mock, OutputTarget, Transcription, findCommonSubstringEndIndex, isEmpty
import { KeyboardStub } from 'keyman/engine/keyboard-storage';
import { ContextManagerBase } from 'keyman/engine/main';
import { WebviewConfiguration } from './configuration.js';
import { Transform } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';

export type OnInsertTextFunc = (deleteLeft: number, text: string, deleteRight: number) => void;

Expand All @@ -17,7 +17,7 @@ export class ContextHost extends Mock {
this.saveState();
}

apply(transform: Transform): void {
apply(transform: LexicalModelTypes.Transform): void {
super.apply(transform);
this.updateHost();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Suggestion, Reversion } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';
import { EventEmitter } from "eventemitter3";
import { OutputTarget } from "keyman/engine/keyboard";

export class ReadySuggestions {
suggestions: Suggestion[];
suggestions: LexicalModelTypes.Suggestion[];
transcriptionID: number;

constructor(suggestions: Suggestion[], id: number) {
constructor(suggestions: LexicalModelTypes.Suggestion[], id: number) {
this.suggestions = suggestions;
this.transcriptionID = id;
}
Expand Down Expand Up @@ -56,7 +56,7 @@ export interface LanguageProcessorSpec extends EventEmitter<LanguageProcessorEve

get state(): StateChangeEnum;

invalidateContext(outputTarget: OutputTarget, layerId: string): Promise<Suggestion[]>;
invalidateContext(outputTarget: OutputTarget, layerId: string): Promise<LexicalModelTypes.Suggestion[]>;

/**
*
Expand All @@ -66,9 +66,9 @@ export interface LanguageProcessorSpec extends EventEmitter<LanguageProcessorEve
* required because layerid can be changed by PostKeystroke
* @returns
*/
applySuggestion(suggestion: Suggestion, outputTarget: OutputTarget, getLayerId: () => string): Promise<Reversion>;
applySuggestion(suggestion: LexicalModelTypes.Suggestion, outputTarget: OutputTarget, getLayerId: () => string): Promise<LexicalModelTypes.Reversion>;

applyReversion(reversion: Reversion, outputTarget: OutputTarget): Promise<Suggestion[]>;
applyReversion(reversion: LexicalModelTypes.Reversion, outputTarget: OutputTarget): Promise<LexicalModelTypes.Suggestion[]>;

get wordbreaksAfterSuggestions(): boolean;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { EventEmitter } from "eventemitter3";
import { Keep, Reversion, Suggestion } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';
import Keep = LexicalModelTypes.Keep;
import Reversion = LexicalModelTypes.Reversion;
import Suggestion = LexicalModelTypes.Suggestion;
import { type LanguageProcessorSpec , ReadySuggestions, type InvalidateSourceEnum, StateChangeHandler } from './languageProcessor.interface.js';
import { type OutputTarget } from "keyman/engine/keyboard";

Expand Down
10 changes: 5 additions & 5 deletions web/src/engine/js-processor/src/outputTarget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ extendString();
// Defines deadkey management in a manner attachable to each element interface.
import { type KeyEvent } from 'keyman/engine/keyboard';
import { Deadkey, DeadkeyTracker } from "./deadkeys.js";
import { ProbabilityMass, Transform } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';

// Also relies on string-extensions provided by the web-utils package.

export function isEmptyTransform(transform: Transform) {
export function isEmptyTransform(transform: LexicalModelTypes.Transform) {
if(!transform) {
return true;
}
return transform.insert === '' && transform.deleteLeft === 0 && (transform.deleteRight ?? 0) === 0;
}

export class TextTransform implements Transform {
export class TextTransform implements LexicalModelTypes.Transform {
readonly insert: string;
readonly deleteLeft: number;
readonly deleteRight: number;
Expand Down Expand Up @@ -64,7 +64,7 @@ export class Transcription {
}
}

export type Alternate = ProbabilityMass<Transform>;
export type Alternate = LexicalModelTypes.ProbabilityMass<LexicalModelTypes.Transform>;

export default abstract class OutputTarget implements OutputTargetInterface {
private _dks: DeadkeyTracker;
Expand Down Expand Up @@ -173,7 +173,7 @@ export default abstract class OutputTarget implements OutputTargetInterface {
this._dks = original._dks.clone();
}

apply(transform: Transform) {
apply(transform: LexicalModelTypes.Transform) {
// Selected text should disappear on any text edit; application of a transform
// certainly qualifies.
this.clearSelection();
Expand Down
4 changes: 2 additions & 2 deletions web/src/engine/js-processor/src/ruleBehavior.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { VariableStoreDictionary } from "keyman/engine/keyboard";
import OutputTarget, { type Transcription } from './outputTarget.js';
import { Mock } from "./mock.js";
import { type VariableStore } from "./systemStores.js";
import { Suggestion } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';

/**
* Represents the commands and state changes that result from a matched keyboard rule.
Expand Down Expand Up @@ -53,7 +53,7 @@ export default class RuleBehavior {
/**
* If predictive text is active, contains a Promise returning predictive Suggestions.
*/
predictionPromise?: Promise<Suggestion[]>;
predictionPromise?: Promise<LexicalModelTypes.Suggestion[]>;

/**
* In reference to https://github.com/keymanapp/keyman/pull/4350#issuecomment-768753852:
Expand Down
10 changes: 5 additions & 5 deletions web/src/engine/main/src/headless/contextWindow.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { CasingForm, Configuration, Context } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';
import { Mock } from "keyman/engine/js-processor";

export default class ContextWindow implements Context {
export default class ContextWindow implements LexicalModelTypes.Context {
// Used to limit the range of context replicated for use of keyboard rules within
// the engine, as used for fat-finger prep / `Alternate` generation.
public static readonly ENGINE_RULE_WINDOW: Configuration = {
public static readonly ENGINE_RULE_WINDOW: LexicalModelTypes.Configuration = {
leftContextCodePoints: 64,
rightContextCodePoints: 32
};
Expand All @@ -15,9 +15,9 @@ export default class ContextWindow implements Context {
startOfBuffer: boolean;
endOfBuffer: boolean;

casingForm?: CasingForm;
casingForm?: LexicalModelTypes.CasingForm;

constructor(mock: Mock, config: Configuration, layerId: string) {
constructor(mock: Mock, config: LexicalModelTypes.Configuration, layerId: string) {
this.left = mock.getTextBeforeCaret();
this.startOfBuffer = this.left._kmwLength() <= config.leftContextCodePoints;
if(!this.startOfBuffer) {
Expand Down
4 changes: 2 additions & 2 deletions web/src/engine/main/src/headless/inputProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from 'keyman/engine/js-processor';

import { TranscriptionCache } from "./transcriptionCache.js";
import { Transform } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';

export class InputProcessor {
public static readonly DEFAULT_OPTIONS: ProcessorInitOptions = {
Expand Down Expand Up @@ -355,7 +355,7 @@ export class InputProcessor {
//
// Also possible that this set of conditions fail for all evaluated alternates.
if(alternateBehavior && !alternateBehavior.beep && pair.p > 0) {
let transform: Transform = alternateBehavior.transcription.transform;
let transform: LexicalModelTypes.Transform = alternateBehavior.transcription.transform;

// Ensure that the alternate's token id matches that of the current keystroke, as we only
// record the matched rule's context (since they match)
Expand Down
6 changes: 5 additions & 1 deletion web/src/engine/main/src/headless/languageProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import { OutputTarget, Transcription, Mock } from "keyman/engine/js-processor";
import { LanguageProcessorEventMap, ModelSpec, StateChangeEnum, ReadySuggestions } from 'keyman/engine/interfaces';
import ContextWindow from "./contextWindow.js";
import { TranscriptionCache } from "./transcriptionCache.js";
import { Capabilities, Configuration, Reversion, Suggestion } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';
import Capabilities = LexicalModelTypes.Capabilities;
import Configuration = LexicalModelTypes.Configuration;
import Reversion = LexicalModelTypes.Reversion;
import Suggestion = LexicalModelTypes.Suggestion;

/* Is more like the model configuration engine */
export class LanguageProcessor extends EventEmitter<LanguageProcessorEventMap> {
Expand Down
14 changes: 7 additions & 7 deletions web/src/engine/osk/src/banner/suggestionBanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { ParsedLengthStyle } from '../lengthStyle.js';
import { getFontSizeStyle } from '../fontSizeUtils.js';
import { getTextMetrics } from '../keyboard-layout/getTextMetrics.js';
import { BannerScrollState } from './bannerScrollState.js';
import { Suggestion } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';

const TOUCHED_CLASS: string = 'kmw-suggest-touched';
const BANNER_SCROLLER_CLASS = 'kmw-suggest-banner-scroller';
Expand Down Expand Up @@ -82,7 +82,7 @@ export class BannerSuggestion {

public readonly rtl: boolean;

private _suggestion: Suggestion;
private _suggestion: LexicalModelTypes.Suggestion;

private index: number;

Expand Down Expand Up @@ -142,18 +142,18 @@ export class BannerSuggestion {
}
}

get suggestion(): Suggestion {
get suggestion(): LexicalModelTypes.Suggestion {
return this._suggestion;
}

/**
* Function update
* @param {Suggestion} suggestion Suggestion from the lexical model
* @param {LexicalModelTypes.Suggestion} suggestion Suggestion from the lexical model
* @param {BannerSuggestionFormatSpec} format Formatting metadata to use for the Suggestion
*
* Update the ID and text of the BannerSuggestionSpec
*/
public update(suggestion: Suggestion, format: BannerSuggestionFormatSpec) {
public update(suggestion: LexicalModelTypes.Suggestion, format: BannerSuggestionFormatSpec) {
this._suggestion = suggestion;

let display = this.generateSuggestionText(this.rtl);
Expand Down Expand Up @@ -384,7 +384,7 @@ export class SuggestionBanner extends Banner {

public readonly type = "suggestion";

private currentSuggestions: Suggestion[] = [];
private currentSuggestions: LexicalModelTypes.Suggestion[] = [];

private options : BannerSuggestion[] = [];
private separators: HTMLElement[] = [];
Expand Down Expand Up @@ -715,7 +715,7 @@ export class SuggestionBanner extends Banner {
* suggestions, including optimization of the banner's layout.
* @param suggestions
*/
public onSuggestionUpdate = (suggestions: Suggestion[]): void => {
public onSuggestionUpdate = (suggestions: LexicalModelTypes.Suggestion[]): void => {
this.currentSuggestions = suggestions;
// Immediately stop all animations and reset options accordingly.
this.highlightAnimation?.cancel();
Expand Down
8 changes: 7 additions & 1 deletion web/src/engine/predictive-text/templates/src/common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// Allows the kmwstring bindings to resolve.
import { CasingForm, Context, Outcome, Suggestion, Transform, WithOutcome } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';
import CasingForm = LexicalModelTypes.CasingForm;
import Context = LexicalModelTypes.Context;
import Outcome = LexicalModelTypes.Outcome;
import Suggestion = LexicalModelTypes.Suggestion;
import Transform = LexicalModelTypes.Transform;
import WithOutcome = LexicalModelTypes.WithOutcome;
import { extendString } from "@keymanapp/web-utils";

extendString();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LexicalModelPunctuation } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';

export enum QuoteBehavior {
noQuotes = "no-quotes",
Expand All @@ -14,7 +14,7 @@ export namespace QuoteBehavior {
* @param punctuation The active `LexicalModelPunctuation` settings
* @param defaultTo The default quote behavior to use (in case the current value is `.default`)
*/
export function apply(behavior: QuoteBehavior, text: string, punctuation: LexicalModelPunctuation, defaultTo: QuoteBehavior): string {
export function apply(behavior: QuoteBehavior, text: string, punctuation: LexicalModelTypes.LexicalModelPunctuation, defaultTo: QuoteBehavior): string {
if(defaultTo == QuoteBehavior.default || !defaultTo) {
throw "Specified quote behavior may be ambiguous - default behavior not specified (may not be .default)";
}
Expand Down
10 changes: 5 additions & 5 deletions web/src/engine/predictive-text/templates/src/tokenization.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// While we _could_ define this within @keymanapp/models-wordbreakers instead, it's probably
// better to leave that package as _just_ the wordbreakers.

import { WordBreakingFunction, USVString, Context } from '@keymanapp/common-types';
import { LexicalModelTypes } from '@keymanapp/common-types';

export interface Token {
text: string,
Expand Down Expand Up @@ -30,8 +30,8 @@ export interface Tokenization {
}

export function tokenize(
wordBreaker: WordBreakingFunction,
context: Partial<Context>,
wordBreaker: LexicalModelTypes.WordBreakingFunction,
context: Partial<LexicalModelTypes.Context>,
options?: {
/** Characters to rejoin to preceding tokens if found immediately pre-caret. */
rejoins?: string[]
Expand Down Expand Up @@ -197,7 +197,7 @@ export function tokenize(
* If the last 'token' before the caret is whitespace, returns `''`.
* @param fullLeftContext the entire left context of the string.
*/
export function getLastPreCaretToken(wordBreaker: WordBreakingFunction, context: Context): string {
export function getLastPreCaretToken(wordBreaker: LexicalModelTypes.WordBreakingFunction, context: LexicalModelTypes.Context): string {
let tokenization = tokenize(wordBreaker, context);
if (tokenization.left.length > 0) {
const lastToken = tokenization.left.pop();
Expand All @@ -214,6 +214,6 @@ export function getLastPreCaretToken(wordBreaker: WordBreakingFunction, context:
// While it is currently identical to getLastWord, this may change in the future.
// It's best not to write ourselves into a corner on this one, as disambiguating later
// would likely be pretty painful.
export function wordbreak(wordBreaker: WordBreakingFunction, context: Context): USVString {
export function wordbreak(wordBreaker: LexicalModelTypes.WordBreakingFunction, context: LexicalModelTypes.Context): LexicalModelTypes.USVString {
return getLastPreCaretToken(wordBreaker, context);
}
16 changes: 15 additions & 1 deletion web/src/engine/predictive-text/templates/src/trie-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,21 @@ import { default as defaultWordBreaker } from "@keymanapp/models-wordbreakers";

import { applyTransform, isHighSurrogate, isSentinel, SENTINEL_CODE_UNIT, transformToSuggestion } from "./common.js";
import { getLastPreCaretToken } from "./tokenization.js";
import { Capabilities, CasingFunction, Configuration, Context, Distribution, LexicalModel, LexicalModelPunctuation, LexiconTraversal, Suggestion, TextWithProbability, Transform, USVString, WithOutcome, WordBreakingFunction } from '@keymanapp/common-types';
import { LexicalModelTypes } from "@keymanapp/common-types";
import Capabilities = LexicalModelTypes.Capabilities;
import CasingFunction = LexicalModelTypes.CasingFunction;
import Configuration = LexicalModelTypes.Configuration;
import Context = LexicalModelTypes.Context;
import Distribution = LexicalModelTypes.Distribution;
import LexicalModel = LexicalModelTypes.LexicalModel;
import LexicalModelPunctuation = LexicalModelTypes.LexicalModelPunctuation;
import LexiconTraversal = LexicalModelTypes.LexiconTraversal;
import Suggestion = LexicalModelTypes.Suggestion;
import TextWithProbability = LexicalModelTypes.TextWithProbability;
import Transform = LexicalModelTypes.Transform;
import USVString = LexicalModelTypes.USVString;
import WithOutcome = LexicalModelTypes.WithOutcome;
import WordBreakingFunction = LexicalModelTypes.WordBreakingFunction;

extendString();

Expand Down
Loading

0 comments on commit b10634e

Please sign in to comment.