diff --git a/common/web/keyboard-processor/build.sh b/common/web/keyboard-processor/build.sh
index 3921063bb9..964370c2fb 100755
--- a/common/web/keyboard-processor/build.sh
+++ b/common/web/keyboard-processor/build.sh
@@ -17,6 +17,7 @@ BUNDLE_CMD="node ${KEYMAN_ROOT}/common/web/es-bundling/build/common-bundle.mjs"
builder_describe \
"Compiles the web-oriented utility function module." \
"@/web/src/tools/testing/recorder-core test" \
+ "@/web/src/engine/js-processor test" \
"@/common/web/keyman-version" \
"@/common/web/es-bundling" \
"@/common/web/types" \
@@ -64,10 +65,10 @@ function do_build() {
--platform node
# Tests
- builder_echo "Bundle tests"
- ${BUNDLE_CMD} "${KEYMAN_ROOT}/common/web/keyboard-processor/build/tests/dom/cases/domKeyboardLoader.spec.js" \
- --out "${KEYMAN_ROOT}/common/web/keyboard-processor/build/tests/dom/domKeyboardLoader.spec.mjs" \
- --format esm
+ # builder_echo "Bundle tests"
+ # ${BUNDLE_CMD} "${KEYMAN_ROOT}/common/web/keyboard-processor/build/tests/dom/cases/domKeyboardLoader.spec.js" \
+ # --out "${KEYMAN_ROOT}/common/web/keyboard-processor/build/tests/dom/domKeyboardLoader.spec.mjs" \
+ # --format esm
# Declaration bundling.
builder_echo "Declaration bundling"
@@ -92,4 +93,4 @@ function do_test() {
builder_run_action configure do_configure
builder_run_action clean rm -rf ./build
builder_run_action build do_build
-builder_run_action test do_test
+# builder_run_action test do_test
diff --git a/common/web/keyboard-processor/src/index.ts b/common/web/keyboard-processor/src/index.ts
index f800691cfa..d9d0b2137f 100644
--- a/common/web/keyboard-processor/src/index.ts
+++ b/common/web/keyboard-processor/src/index.ts
@@ -29,18 +29,12 @@ export * from "./text/codes.js";
export * from "./text/deadkeys.js";
export { default as DefaultRules } from "./text/defaultRules.js";
export * from "./text/defaultRules.js";
-export { default as KeyboardInterface } from "./text/kbdInterface.js";
-export * from "./text/kbdInterface.js";
-export { default as KeyboardProcessor } from "./text/keyboardProcessor.js";
-export * from "./text/keyboardProcessor.js";
export { default as KeyEvent } from "./text/keyEvent.js";
export * from "./text/keyEvent.js";
export { default as KeyMapping } from "./text/keyMapping.js";
export { default as OutputTarget } from "./text/outputTarget.js";
export * from "./text/outputTarget.js";
-export { default as RuleBehavior } from "./text/ruleBehavior.js";
export * from "./text/stringDivergence.js";
-export * from "./text/systemStores.js";
export * from "@keymanapp/web-utils";
@@ -48,4 +42,4 @@ export * from "@keymanapp/web-utils";
// Without the line below... OutputTarget would likely be aliased there, as it's
// the last `export { default as _ }` => `export * from` pairing seen above.
-export default undefined;
\ No newline at end of file
+export default undefined;
diff --git a/common/web/keyboard-processor/src/keyboards/keyboard.ts b/common/web/keyboard-processor/src/keyboards/keyboard.ts
index 5312d825a6..d791d6ea75 100644
--- a/common/web/keyboard-processor/src/keyboards/keyboard.ts
+++ b/common/web/keyboard-processor/src/keyboards/keyboard.ts
@@ -6,11 +6,11 @@ import type OutputTarget from "../text/outputTarget.js";
import { ModifierKeyConstants, TouchLayout } from "@keymanapp/common-types";
type TouchLayoutSpec = TouchLayout.TouchLayoutPlatform & { isDefault?: boolean};
-import type { ComplexKeyboardStore } from "../text/kbdInterface.js";
-
import { Version, DeviceSpec } from "@keymanapp/web-utils";
import StateKeyMap from "./stateKeyMap.js";
+type ComplexKeyboardStore = ( string | { t: 'd', d: number } | { ['t']: 'b' })[];
+
/**
* Stores preprocessed properties of a keyboard for quick retrieval later.
*/
diff --git a/common/web/keyboard-processor/src/keyboards/keyboardHarness.ts b/common/web/keyboard-processor/src/keyboards/keyboardHarness.ts
index 671c8fefd7..109d209067 100644
--- a/common/web/keyboard-processor/src/keyboards/keyboardHarness.ts
+++ b/common/web/keyboard-processor/src/keyboards/keyboardHarness.ts
@@ -1,5 +1,6 @@
import Keyboard from "./keyboard.js";
import Codes from "../text/codes.js";
+import { DeviceSpec } from '@keymanapp/web-utils';
/**
* Defines members of the top-level `keyman` global object necessary to guarantee
@@ -40,6 +41,8 @@ export const MinimalKeymanGlobal: KeyboardKeymanGlobal = {
export class KeyboardHarness {
public readonly _jsGlobal: any;
public readonly keymanGlobal: KeyboardKeymanGlobal;
+ activeDevice: DeviceSpec;
+
/**
* Constructs and configures a harness for receiving dynamically-loaded Keyman keyboards.
diff --git a/common/web/keyboard-processor/src/text/defaultRules.ts b/common/web/keyboard-processor/src/text/defaultRules.ts
index 931eb5200b..94acb02688 100644
--- a/common/web/keyboard-processor/src/text/defaultRules.ts
+++ b/common/web/keyboard-processor/src/text/defaultRules.ts
@@ -1,32 +1,28 @@
-// TODO: Move to separate folder: 'codes'
-// We should start splitting off code needed by keyboards even without a KeyboardProcessor active.
-// There's an upcoming `/common/web/types` package that 'codes' and 'keyboards' may fit well within.
+/*
+ * Keyman is copyright (C) SIL International. MIT License.
+ *
+ * Implementation of default rules
+ */
-import { ModifierKeyConstants} from '@keymanapp/common-types';
-import Codes from "./codes.js";
-import type KeyEvent from "./keyEvent.js";
-import type OutputTarget from "./outputTarget.js";
-
-// The only members referenced are to produce warning and error logs. A little abstraction
-// via an optional 'logger' interface can maintain it while facilitating a the split alluded
-// to above.
-//
-// Alternatively, we could just... not take in the parameter at all, which'd also facilitate
-// the future modularization effort.
-import RuleBehavior from "./ruleBehavior.js";
+import { ModifierKeyConstants } from '@keymanapp/common-types';
+import Codes from './codes.js';
+import type KeyEvent from './keyEvent.js';
+import type OutputTarget from './outputTarget.js';
export enum EmulationKeystrokes {
Enter = '\n',
Backspace = '\b'
}
+export class LogMessages {
+ errorLog?: string;
+ warningLog?: string;
+}
+
/**
* Defines a collection of static library functions that define KeymanWeb's default (implied) keyboard rule behaviors.
*/
export default class DefaultRules {
- public constructor() {
- }
-
codeForEvent(Lkc: KeyEvent) {
return Codes.keyCodes[Lkc.kName] || Lkc.Lcode;;
}
@@ -35,7 +31,7 @@ export default class DefaultRules {
* Serves as a default keycode lookup table. This may be referenced safely by mnemonic handling without fear of side-effects.
* Also used by Processor.defaultRuleBehavior to generate output after filtering for special cases.
*/
- public forAny(Lkc: KeyEvent, isMnemonic: boolean, ruleBehavior?: RuleBehavior) {
+ public forAny(Lkc: KeyEvent, isMnemonic: boolean, logMessages?: LogMessages): string {
var char = '';
// A pretty simple table of lookups, corresponding VERY closely to the original defaultKeyOutput.
@@ -43,9 +39,9 @@ export default class DefaultRules {
return char;
} else if(!isMnemonic && ((char = this.forNumpadKeys(Lkc)) != null)) {
return char;
- } else if((char = this.forUnicodeKeynames(Lkc, ruleBehavior)) != null) {
+ } else if((char = this.forUnicodeKeynames(Lkc, logMessages)) != null) {
return char;
- } else if((char = this.forBaseKeys(Lkc, ruleBehavior)) != null) {
+ } else if((char = this.forBaseKeys(Lkc, logMessages)) != null) {
return char;
} else {
// // For headless and embeddded, we may well allow '\t'. It's DOM mode that has other uses.
@@ -152,7 +148,7 @@ export default class DefaultRules {
// Test for fall back to U_xxxxxx key id
// For this first test, we ignore the keyCode and use the keyName
- public forUnicodeKeynames(Lkc: KeyEvent, ruleBehavior?: RuleBehavior) {
+ public forUnicodeKeynames(Lkc: KeyEvent, logMessages?: LogMessages) {
const keyName = Lkc.kName;
// Test for fall back to U_xxxxxx key id
@@ -169,8 +165,8 @@ export default class DefaultRules {
// Code points [U_0000 - U_001F] and [U_0080 - U_009F] refer to Unicode C0 and C1 control codes.
// Check the codePoint number and do not allow output of these codes via U_xxxxxx shortcuts.
// Also handles invalid identifiers (e.g. `U_ghij`) for which parseInt returns NaN
- if(ruleBehavior) {
- ruleBehavior.errorLog = ("Suppressing Unicode control code in " + keyName);
+ if(logMessages) {
+ logMessages.errorLog = ("Suppressing Unicode control code in " + keyName);
}
// We'll attempt to add valid chars
continue;
@@ -185,17 +181,17 @@ export default class DefaultRules {
// Test for otherwise unimplemented keys on the the base default & shift layers.
// Those keys must be blocked by keyboard rules if intentionally unimplemented; otherwise, this function will trigger.
- public forBaseKeys(Lkc: KeyEvent, ruleBehavior?: RuleBehavior) {
+ public forBaseKeys(Lkc: KeyEvent, logMessages?: LogMessages) {
let n = Lkc.Lcode;
let keyShiftState = Lkc.Lmodifiers;
// check if exact match to SHIFT's code. Only the 'default' and 'shift' layers should have default key outputs.
// TODO: Extend to allow AltGr as well - better mnemonic support.
- if(keyShiftState == ModifierKeyConstants.K_SHIFTFLAG) {
+ if (keyShiftState == ModifierKeyConstants.K_SHIFTFLAG) {
keyShiftState = 1;
} else if(keyShiftState != 0) {
- if(ruleBehavior) {
- ruleBehavior.warningLog = "KMW only defines default key output for the 'default' and 'shift' layers!";
+ if(logMessages) {
+ logMessages.warningLog = "KMW only defines default key output for the 'default' and 'shift' layers!";
}
return null;
}
@@ -216,8 +212,8 @@ export default class DefaultRules {
return keyShiftState ? '|' : '\\';
}
} catch (e) {
- if(ruleBehavior) {
- ruleBehavior.errorLog = "Error detected with default mapping for key: code = " + n + ", shift state = " + (keyShiftState == 1 ? 'shift' : 'default');
+ if(logMessages) {
+ logMessages.errorLog = "Error detected with default mapping for key: code = " + n + ", shift state = " + (keyShiftState == 1 ? 'shift' : 'default');
}
}
diff --git a/common/web/keyboard-processor/src/text/keyEvent.ts b/common/web/keyboard-processor/src/text/keyEvent.ts
index a38992a3a1..7d6483d0e9 100644
--- a/common/web/keyboard-processor/src/text/keyEvent.ts
+++ b/common/web/keyboard-processor/src/text/keyEvent.ts
@@ -10,12 +10,12 @@ import type Keyboard from "../keyboards/keyboard.js";
import { type DeviceSpec } from "@keymanapp/web-utils";
import Codes from './codes.js';
-import DefaultRules from './defaultRules.js';
+import DefaultRules from "./defaultRules.js";
import { ActiveKeyBase } from "../index.js";
// Represents a probability distribution over a keyboard's keys.
// Defined here to avoid compilation issues.
-export type KeyDistribution = {keySpec: ActiveKeyBase, p: number}[];
+export type KeyDistribution = { keySpec: ActiveKeyBase, p: number }[];
/**
* A simple instance of the standard 'default rules' for keystroke processing from the
@@ -188,4 +188,4 @@ export default class KeyEvent implements KeyEventSpec {
}
}
}
-};
\ No newline at end of file
+};
diff --git a/common/web/keyboard-processor/tests/dom/readme.md b/common/web/keyboard-processor/tests/dom/readme.md
deleted file mode 100644
index 153b7f4a1e..0000000000
--- a/common/web/keyboard-processor/tests/dom/readme.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Automated tests in this subfolder and its children are designed to facilitate simple, browser-independent
-unit tests that are DOM-reliant.
-
-Tests for anything that may reasonably vary depending upon the browser used to run the code should go under
-the "integrated" folder instead.
\ No newline at end of file
diff --git a/common/web/keyboard-processor/tests/dom/web-test-runner.CI.config.mjs b/common/web/keyboard-processor/tests/dom/web-test-runner.CI.config.mjs
deleted file mode 100644
index d18a8a9cb0..0000000000
--- a/common/web/keyboard-processor/tests/dom/web-test-runner.CI.config.mjs
+++ /dev/null
@@ -1,13 +0,0 @@
-// @ts-check
-import BASE_CONFIG from './web-test-runner.config.mjs';
-import teamcityReporter from '@keymanapp/common-test-resources/test-runner-TC-reporter.mjs';
-import { sessionStabilityReporter } from '@keymanapp/common-test-resources/test-runner-stability-reporter.mjs';
-
-/** @type {import('@web/test-runner').TestRunnerConfig} */
-export default {
- ...BASE_CONFIG,
- reporters: [
- teamcityReporter(), /* custom-written, for CI-friendly reports */
- sessionStabilityReporter({ciMode: true})
- ]
-}
\ No newline at end of file
diff --git a/common/web/keyboard-processor/tests/dom/web-test-runner.config.mjs b/common/web/keyboard-processor/tests/dom/web-test-runner.config.mjs
deleted file mode 100644
index 76651182ac..0000000000
--- a/common/web/keyboard-processor/tests/dom/web-test-runner.config.mjs
+++ /dev/null
@@ -1,62 +0,0 @@
-// @ts-check
-import { devices, playwrightLauncher } from '@web/test-runner-playwright';
-import { esbuildPlugin } from '@web/dev-server-esbuild';
-import { defaultReporter, summaryReporter } from '@web/test-runner';
-import { LauncherWrapper, sessionStabilityReporter } from '@keymanapp/common-test-resources/test-runner-stability-reporter.mjs';
-import { importMapsPlugin } from '@web/dev-server-import-maps';
-import { dirname, resolve } from 'path';
-import { fileURLToPath } from 'url';
-
-const dir = dirname(fileURLToPath(import.meta.url));
-const KEYMAN_ROOT = resolve(dir, '../../../../..');
-
-/** @type {import('@web/test-runner').TestRunnerConfig} */
-export default {
- // debug: true,
- browsers: [
- new LauncherWrapper(playwrightLauncher({ product: 'chromium' })),
- new LauncherWrapper(playwrightLauncher({ product: 'firefox' })),
- new LauncherWrapper(playwrightLauncher({ product: 'webkit', concurrency: 1 })),
- ],
- concurrency: 10,
- nodeResolve: true,
- files: [
- 'build/tests/dom/**/*.spec.mjs'
- ],
- middleware: [
- // Rewrites short-hand paths for test resources, making them fully relative to the repo root.
- function rewriteResourcePath(context, next) {
- if(context.url.startsWith('/resources/')) {
- context.url = '/common/test' + context.url;
- }
-
- return next();
- }
- ],
- plugins: [
- esbuildPlugin({ts: true, target: 'auto'}),
- importMapsPlugin({
- inject: {
- importMap: {
- // Redirects `eventemitter3` imports to the bundled ESM library. The standard import is an
- // ESM wrapper around the CommonJS implementation, and WTR fails when it hits the CommonJS.
- imports: {
- 'eventemitter3': '/node_modules/eventemitter3/dist/eventemitter3.esm.js'
- }
- }
- }
- })
- ],
- reporters: [
- summaryReporter({}), /* local-dev mocha-style */
- sessionStabilityReporter({}),
- defaultReporter({})
- ],
- /*
- Un-comment the next two lines for easy interactive debugging; it'll launch the
- test page in your preferred browser.
- */
- // open: true,
- // manual: true,
- rootDir: KEYMAN_ROOT
-}
diff --git a/common/web/keyboard-processor/tests/tsconfig.json b/common/web/keyboard-processor/tests/tsconfig.json
deleted file mode 100644
index 0e978545b8..0000000000
--- a/common/web/keyboard-processor/tests/tsconfig.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "extends": "../tsconfig.json",
- "compilerOptions": {
- "baseUrl": "../",
- "outDir": "../build/tests/",
- "tsBuildInfoFile": "../build/tests/tsconfig.tsbuildinfo",
- "rootDir": "./"
- },
- "include": [ "./dom/**/*.ts"],
- "exclude": []
-}
diff --git a/common/web/keyboard-processor/tsconfig.all.json b/common/web/keyboard-processor/tsconfig.all.json
index dabb262d9c..79f10644d1 100644
--- a/common/web/keyboard-processor/tsconfig.all.json
+++ b/common/web/keyboard-processor/tsconfig.all.json
@@ -9,7 +9,6 @@
"references": [
{ "path": "./src/keyboards/loaders/tsconfig.dom.json" },
{ "path": "./src/keyboards/loaders/tsconfig.node.json" },
- { "path": "./tests/tsconfig.json" },
],
// Actual main-body compilation is in tsconfig.json. This config is just a wrapper
// to trigger all three components at once.
diff --git a/web/README.md b/web/README.md
index 1249805165..775f303df5 100644
--- a/web/README.md
+++ b/web/README.md
@@ -82,6 +82,7 @@ title: Dependency Graph
graph TD;
OSK["/web/src/engine/osk"];
KP["@keymanapp/keyboard-processor
(/common/web/keyboard-processor)"];
+ JSProc["/web/src/engine/js-processor"];
OSK-->KP;
WebUtils["@keymanapp/web-utils
(/common/web/utils)"];
KP---->WebUtils;
@@ -107,6 +108,7 @@ graph TD;
Fully headless components`"]
direction LR
KP;
+ JSProc-->KP;
WebUtils;
PredText;
Gestures;
@@ -127,9 +129,9 @@ graph TD;
OSK-->Gestures;
Interfaces["/web/src/engine/interfaces"];
Interfaces-->KP;
+ Interfaces-->JSProc;
OSK-->Interfaces;
CommonEngine["/web/src/engine/main"];
- CommonEngine-->Interfaces;
CommonEngine-->Device;
CommonEngine-->KeyboardCache;
CommonEngine-->OSK;
diff --git a/web/build.sh b/web/build.sh
index 7248f5c35a..6f4737710a 100755
--- a/web/build.sh
+++ b/web/build.sh
@@ -27,6 +27,7 @@ builder_describe "Builds engine modules for Keyman Engine for Web (KMW)." \
":engine/dom-utils A common subset of function used for DOM calculations, layout, etc" \
":engine/events Specialized classes utilized to support KMW API events" \
":engine/element-wrappers Subset used to integrate with website elements" \
+ ":engine/js-processor Build JS processor for KMW" \
":engine/main Builds all common code used by KMW's app/-level targets" \
":engine/osk Builds the Web OSK module" \
":engine/package-cache Subset used to collate keyboards and request them from the cloud" \
@@ -57,6 +58,7 @@ builder_describe_outputs \
build:engine/dom-utils "/web/build/engine/dom-utils/obj/index.js" \
build:engine/events "/web/build/engine/events/lib/index.mjs" \
build:engine/element-wrappers "/web/build/engine/element-wrappers/lib/index.mjs" \
+ build:engine/js-processor "/web/build/engine/js-processor/lib/index.mjs" \
build:engine/main "/web/build/engine/main/lib/index.mjs" \
build:engine/osk "/web/build/engine/osk/lib/index.mjs" \
build:engine/package-cache "/web/build/engine/package-cache/lib/index.mjs" \
diff --git a/web/package.json b/web/package.json
index 458ea85de0..4baff29490 100644
--- a/web/package.json
+++ b/web/package.json
@@ -37,6 +37,11 @@
"types": "./build/engine/events/obj/index.d.ts",
"import": "./build/engine/events/obj/index.js"
},
+ "./engine/js-processor": {
+ "es6-bundling": "./src/engine/js-processor/src/index.ts",
+ "types": "./build/engine/js-processor/obj/index.d.ts",
+ "import": "./build/engine/js-processor/obj/index.js"
+ },
"./engine/package-cache": {
"es6-bundling": "./src/engine/package-cache/src/index.ts",
"types": "./build/engine/package-cache/obj/index.d.ts",
diff --git a/web/src/app/browser/src/beepHandler.ts b/web/src/app/browser/src/beepHandler.ts
index 3659f8d7fd..eb6d6583ee 100644
--- a/web/src/app/browser/src/beepHandler.ts
+++ b/web/src/app/browser/src/beepHandler.ts
@@ -1,4 +1,4 @@
-import { type KeyboardInterface } from '@keymanapp/keyboard-processor';
+import { type KeyboardInterface } from 'keyman/engine/js-processor';
import { DesignIFrame, OutputTarget } from 'keyman/engine/element-wrappers';
// Utility object used to handle beep (keyboard error response) operations.
diff --git a/web/src/app/browser/src/configuration.ts b/web/src/app/browser/src/configuration.ts
index 07be8264e7..4f2f268438 100644
--- a/web/src/app/browser/src/configuration.ts
+++ b/web/src/app/browser/src/configuration.ts
@@ -1,7 +1,8 @@
import { EngineConfiguration, InitOptionSpec, InitOptionDefaults } from "keyman/engine/main";
import { OutputTarget as DOMOutputTarget } from 'keyman/engine/element-wrappers';
-import { isEmptyTransform, OutputTarget, RuleBehavior } from '@keymanapp/keyboard-processor';
+import { isEmptyTransform, OutputTarget } from '@keymanapp/keyboard-processor';
+import { RuleBehavior } from 'keyman/engine/js-processor';
import { AlertHost } from "./utils/alertHost.js";
import { whenDocumentReady } from "./utils/documentReady.js";
diff --git a/web/src/app/browser/src/hardwareEventKeyboard.ts b/web/src/app/browser/src/hardwareEventKeyboard.ts
index 29e867aa13..f6874fc77b 100644
--- a/web/src/app/browser/src/hardwareEventKeyboard.ts
+++ b/web/src/app/browser/src/hardwareEventKeyboard.ts
@@ -1,4 +1,5 @@
-import { Codes, DeviceSpec, KeyEvent, KeyMapping, Keyboard, KeyboardProcessor } from '@keymanapp/keyboard-processor';
+import { Codes, DeviceSpec, KeyEvent, KeyMapping, Keyboard } from '@keymanapp/keyboard-processor';
+import { KeyboardProcessor } from 'keyman/engine/js-processor';
import { ModifierKeyConstants } from '@keymanapp/common-types';
import { HardKeyboard, processForMnemonicsAndLegacy } from 'keyman/engine/main';
diff --git a/web/src/app/webview/src/keymanEngine.ts b/web/src/app/webview/src/keymanEngine.ts
index ba98f8c477..dfae058a65 100644
--- a/web/src/app/webview/src/keymanEngine.ts
+++ b/web/src/app/webview/src/keymanEngine.ts
@@ -1,4 +1,5 @@
-import { DefaultRules, DeviceSpec, RuleBehavior } from '@keymanapp/keyboard-processor'
+import { DeviceSpec, DefaultRules } from '@keymanapp/keyboard-processor'
+import { RuleBehavior } from 'keyman/engine/js-processor';
import { KeymanEngine as KeymanEngineBase, KeyboardInterface } from 'keyman/engine/main';
import { AnchoredOSKView, ViewConfiguration, StaticActivator } from 'keyman/engine/osk';
import { getAbsoluteX, getAbsoluteY } from 'keyman/engine/dom-utils';
diff --git a/web/src/engine/events/src/index.ts b/web/src/engine/events/src/index.ts
index 2d95307bc9..ee5674b66c 100644
--- a/web/src/engine/events/src/index.ts
+++ b/web/src/engine/events/src/index.ts
@@ -1,4 +1,3 @@
export { DomEventTracker } from './domEventTracker.js';
export { EmitterListenerSpy } from './emitterListenerSpy.js';
-export * from './keyEventSource.interface.js';
export * from './legacyEventEmitter.js';
\ No newline at end of file
diff --git a/web/src/engine/interfaces/build.sh b/web/src/engine/interfaces/build.sh
index ca61e64865..528083d4d8 100755
--- a/web/src/engine/interfaces/build.sh
+++ b/web/src/engine/interfaces/build.sh
@@ -15,6 +15,7 @@ SUBPROJECT_NAME=engine/interfaces
builder_describe "Builds configuration subclasses used by the Keyman Engine for Web (KMW)." \
"@/common/web/es-bundling" \
"@/common/web/keyboard-processor" \
+ "@/web/src/engine/js-processor" \
"clean" \
"configure" \
"build" \
diff --git a/web/src/engine/interfaces/src/prediction/predictionContext.ts b/web/src/engine/interfaces/src/prediction/predictionContext.ts
index d47bf4b8e2..90427c3020 100644
--- a/web/src/engine/interfaces/src/prediction/predictionContext.ts
+++ b/web/src/engine/interfaces/src/prediction/predictionContext.ts
@@ -1,6 +1,7 @@
import { EventEmitter } from "eventemitter3";
import { type LanguageProcessorSpec , ReadySuggestions, type InvalidateSourceEnum, StateChangeHandler } from './languageProcessor.interface.js';
-import { type KeyboardProcessor, type OutputTarget } from "@keymanapp/keyboard-processor";
+import { type OutputTarget } from "@keymanapp/keyboard-processor";
+import { type KeyboardProcessor } from 'keyman/engine/js-processor';
interface PredictionContextEventMap {
update: (suggestions: Suggestion[]) => void;
diff --git a/web/src/engine/interfaces/tsconfig.json b/web/src/engine/interfaces/tsconfig.json
index d5a193e021..634e62bada 100644
--- a/web/src/engine/interfaces/tsconfig.json
+++ b/web/src/engine/interfaces/tsconfig.json
@@ -13,5 +13,6 @@
"references": [
{ "path": "../../../../common/web/keyboard-processor" },
+ { "path": "../js-processor" }
]
}
diff --git a/web/src/engine/js-processor/build.sh b/web/src/engine/js-processor/build.sh
new file mode 100755
index 0000000000..57adbd1dd2
--- /dev/null
+++ b/web/src/engine/js-processor/build.sh
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+
+## START STANDARD BUILD SCRIPT INCLUDE
+# adjust relative paths as necessary
+THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
+. "${THIS_SCRIPT%/*}/../../../../resources/build/builder.inc.sh"
+## END STANDARD BUILD SCRIPT INCLUDE
+
+SUBPROJECT_NAME=engine/js-processor
+
+. "${KEYMAN_ROOT}/web/common.inc.sh"
+. "${KEYMAN_ROOT}/resources/shellHelperFunctions.sh"
+
+# ################################ Main script ################################
+
+builder_describe "Builds configuration subclasses used by the Keyman Engine for Web (KMW)." \
+ "clean" \
+ "configure" \
+ "build" \
+ "test" \
+ "--ci+ Set to utilize CI-based test configurations & reporting."
+
+builder_describe_outputs \
+ configure "/node_modules" \
+ build "/web/build/${SUBPROJECT_NAME}/lib/index.mjs"
+
+builder_parse "$@"
+
+#### Build action definitions ####
+
+do_build () {
+ compile "${SUBPROJECT_NAME}"
+
+ ${BUNDLE_CMD} "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
+ --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
+ --format esm
+}
+
+builder_run_action configure verify_npm_setup
+builder_run_action clean rm -rf "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}"
+builder_run_action build do_build
diff --git a/web/src/engine/js-processor/src/index.ts b/web/src/engine/js-processor/src/index.ts
new file mode 100644
index 0000000000..f87a044bd7
--- /dev/null
+++ b/web/src/engine/js-processor/src/index.ts
@@ -0,0 +1,6 @@
+export { default as KeyboardProcessor } from "./keyboardProcessor.js";
+export * from "./keyboardProcessor.js";
+export { default as RuleBehavior } from "./ruleBehavior.js";
+export * from './kbdInterface.js';
+export { default as KeyboardInterface } from "./kbdInterface.js";
+export * from "./systemStores.js";
diff --git a/common/web/keyboard-processor/src/text/kbdInterface.ts b/web/src/engine/js-processor/src/kbdInterface.ts
similarity index 96%
rename from common/web/keyboard-processor/src/text/kbdInterface.ts
rename to web/src/engine/js-processor/src/kbdInterface.ts
index 438d328f0d..6272637d04 100644
--- a/common/web/keyboard-processor/src/text/kbdInterface.ts
+++ b/web/src/engine/js-processor/src/kbdInterface.ts
@@ -7,18 +7,9 @@
import { type DeviceSpec } from "@keymanapp/web-utils";
import { ModifierKeyConstants } from '@keymanapp/common-types';
-
-import Codes from "./codes.js";
-import type KeyEvent from "./keyEvent.js";
-import type { Deadkey } from "./deadkeys.js";
-import KeyMapping from "./keyMapping.js";
-import { SystemStore, MutableSystemStore, PlatformSystemStore } from "./systemStores.js";
-import type { VariableStoreSerializer } from "./keyboardProcessor.js";
-import type OutputTarget from "./outputTarget.js";
-import { Mock } from "./outputTarget.js";
+import { Codes, type KeyEvent, type Deadkey, KeyMapping, type OutputTarget, Mock, Keyboard, KeyboardHarness, KeyboardKeymanGlobal, VariableStoreDictionary } from "@keymanapp/keyboard-processor";
import RuleBehavior from "./ruleBehavior.js";
-import Keyboard, { VariableStoreDictionary } from "../keyboards/keyboard.js";
-import { KeyboardHarness, KeyboardKeymanGlobal } from "../keyboards/keyboardHarness.js";
+import { ComplexKeyboardStore, type KeyboardStore, KeyboardStoreElement, SystemStoreIDs, SystemStore, MutableSystemStore, PlatformSystemStore, VariableStore, VariableStoreSerializer } from "./systemStores.js";
//#endregion
@@ -30,20 +21,6 @@ export class KeyInformation {
modifiers: number;
}
-/*
-* Type alias definitions to reflect the parameters of the fullContextMatch() callback (KMW 10+).
-* No constructors or methods since keyboards will not utilize the same backing prototype, and
-* property names are shorthanded to promote minification.
-*/
-type PlainKeyboardStore = string;
-
-export type KeyboardStoreElement = (string|StoreNonCharEntry);
-export type ComplexKeyboardStore = KeyboardStoreElement[];
-
-type KeyboardStore = PlainKeyboardStore | ComplexKeyboardStore;
-
-export type VariableStore = {[name: string]: string};
-
type RuleChar = string;
class RuleDeadkey {
@@ -70,7 +47,7 @@ class ContextAny {
/**
* If set to true, negates the 'any'.
*/
- ['n']: boolean|0|1;
+ ['n']: boolean | 0 | 1;
}
class RuleIndex {
@@ -115,7 +92,7 @@ class StoreBeep {
type ContextNonCharEntry = RuleDeadkey | ContextAny | RuleIndex | ContextEx | ContextNul;
type ContextEntry = RuleChar | ContextNonCharEntry;
-type StoreNonCharEntry = RuleDeadkey | StoreBeep;
+export type StoreNonCharEntry = RuleDeadkey | StoreBeep;
/**
* Cache of context storing and retrieving return values from KC
@@ -183,13 +160,6 @@ class CachedContextEx {
}
};
-export enum SystemStoreIDs {
- TSS_LAYER = 33,
- TSS_PLATFORM = 31,
- TSS_NEWLAYER = 42,
- TSS_OLDLAYER = 43
-}
-
//#endregion
export default class KeyboardInterface extends KeyboardHarness {
diff --git a/common/web/keyboard-processor/src/text/keyboardProcessor.ts b/web/src/engine/js-processor/src/keyboardProcessor.ts
similarity index 95%
rename from common/web/keyboard-processor/src/text/keyboardProcessor.ts
rename to web/src/engine/js-processor/src/keyboardProcessor.ts
index 836c9912a6..12efa4e951 100644
--- a/common/web/keyboard-processor/src/text/keyboardProcessor.ts
+++ b/web/src/engine/js-processor/src/keyboardProcessor.ts
@@ -1,23 +1,21 @@
+/*
+ * Keyman is copyright (C) SIL International. MIT License.
+ *
+ * Implementation of the JavaScript keyboard processor
+ */
+
// #region Big ol' list of imports
import { EventEmitter } from 'eventemitter3';
-
-import Codes from "./codes.js";
-import type Keyboard from "../keyboards/keyboard.js";
-import { MinimalKeymanGlobal } from '../keyboards/keyboardHarness.js';
-import KeyEvent from "./keyEvent.js";
-import { Layouts } from "../keyboards/defaultLayouts.js";
-import type { MutableSystemStore } from "./systemStores.js";
-
-import DefaultRules, { EmulationKeystrokes } from "./defaultRules.js";
-import type OutputTarget from "./outputTarget.js";
-import { Mock } from "./outputTarget.js";
-
-import KeyboardInterface, { SystemStoreIDs, VariableStore } from "./kbdInterface.js";
-import RuleBehavior from "./ruleBehavior.js";
-
-import { DeviceSpec, globalObject } from "@keymanapp/web-utils";
import { ModifierKeyConstants } from '@keymanapp/common-types';
+import {
+ Codes, type Keyboard, MinimalKeymanGlobal, KeyEvent, Layouts,
+ type OutputTarget, Mock, DefaultRules, EmulationKeystrokes
+} from "@keymanapp/keyboard-processor";
+import RuleBehavior from "./ruleBehavior.js";
+import KeyboardInterface from './kbdInterface.js';
+import { DeviceSpec, globalObject } from "@keymanapp/web-utils";
+import { type MutableSystemStore, SystemStoreIDs } from "./systemStores.js";
// #endregion
@@ -26,11 +24,6 @@ import { ModifierKeyConstants } from '@keymanapp/common-types';
export type BeepHandler = (outputTarget: OutputTarget) => void;
export type LogMessageHandler = (str: string) => void;
-export interface VariableStoreSerializer {
- loadStore(keyboardID: string, storeName: string): VariableStore;
- saveStore(keyboardID: string, storeName: string, storeMap: VariableStore): void;
-}
-
export interface ProcessorInitOptions {
baseLayout?: string;
keyboardInterface?: KeyboardInterface;
@@ -174,7 +167,7 @@ export default class KeyboardProcessor extends EventEmitter {
let isMnemonic = this.activeKeyboard && this.activeKeyboard.isMnemonic;
if(!matched) {
- if((char = this.defaultRules.forAny(Lkc, isMnemonic)) != null) {
+ if((char = this.defaultRules.forAny(Lkc, isMnemonic, ruleBehavior)) != null) {
special = this.defaultRules.forSpecialEmulation(Lkc)
if(special == EmulationKeystrokes.Backspace) {
// A browser's default backspace may fail to delete both parts of an SMP character.
@@ -277,7 +270,8 @@ export default class KeyboardProcessor extends EventEmitter {
const lockNames = ['CAPS', 'NUM_LOCK', 'SCROLL_LOCK'] as const;
const lockKeys = ['K_CAPS', 'K_NUMLOCK', 'K_SCROLL'] as const;
- const lockModifiers = [ ModifierKeyConstants.CAPITALFLAG, ModifierKeyConstants.NUMLOCKFLAG, ModifierKeyConstants.SCROLLFLAG] as const;
+ const lockModifiers = [ModifierKeyConstants.CAPITALFLAG, ModifierKeyConstants.NUMLOCKFLAG, ModifierKeyConstants.SCROLLFLAG] as const;
+
if(!this.activeKeyboard) {
return true;
@@ -329,6 +323,8 @@ export default class KeyboardProcessor extends EventEmitter {
const lockModifiers = [ModifierKeyConstants.CAPITALFLAG, ModifierKeyConstants.NUMLOCKFLAG, ModifierKeyConstants.SCROLLFLAG] as const;
const noLockModifers = [ModifierKeyConstants.NOTCAPITALFLAG, ModifierKeyConstants.NOTNUMLOCKFLAG, ModifierKeyConstants.NOTSCROLLFLAG] as const;
+
+
for(let i=0; i < lockKeys.length; i++) {
const key = lockKeys[i];
const flag = this.stateKeys[key];
diff --git a/common/web/keyboard-processor/src/text/ruleBehavior.ts b/web/src/engine/js-processor/src/ruleBehavior.ts
similarity index 96%
rename from common/web/keyboard-processor/src/text/ruleBehavior.ts
rename to web/src/engine/js-processor/src/ruleBehavior.ts
index e5d669e909..08881eabcc 100644
--- a/common/web/keyboard-processor/src/text/ruleBehavior.ts
+++ b/web/src/engine/js-processor/src/ruleBehavior.ts
@@ -1,9 +1,8 @@
///
import KeyboardProcessor from "./keyboardProcessor.js";
-import OutputTarget, { Mock, type Transcription } from "./outputTarget.js";
-import { VariableStoreDictionary } from "../keyboards/keyboard.js";
-import type { VariableStore } from "./kbdInterface.js";
+import { OutputTarget, Mock, type Transcription, VariableStoreDictionary } from "@keymanapp/keyboard-processor";
+import { type VariableStore } from "./systemStores.js";
/**
* Represents the commands and state changes that result from a matched keyboard rule.
diff --git a/common/web/keyboard-processor/src/text/systemStores.ts b/web/src/engine/js-processor/src/systemStores.ts
similarity index 74%
rename from common/web/keyboard-processor/src/text/systemStores.ts
rename to web/src/engine/js-processor/src/systemStores.ts
index 13184baafe..9d02dbddbc 100644
--- a/common/web/keyboard-processor/src/text/systemStores.ts
+++ b/web/src/engine/js-processor/src/systemStores.ts
@@ -1,5 +1,31 @@
-import type KeyboardInterface from "./kbdInterface.js";
-import { SystemStoreIDs } from "./kbdInterface.js";
+import { type KeyboardHarness } from '@keymanapp/keyboard-processor';
+import { StoreNonCharEntry } from './kbdInterface.js';
+
+export enum SystemStoreIDs {
+ TSS_LAYER = 33,
+ TSS_PLATFORM = 31,
+ TSS_NEWLAYER = 42,
+ TSS_OLDLAYER = 43
+}
+
+/*
+* Type alias definitions to reflect the parameters of the fullContextMatch() callback (KMW 10+).
+* No constructors or methods since keyboards will not utilize the same backing prototype, and
+* property names are shorthanded to promote minification.
+*/
+type PlainKeyboardStore = string;
+
+export type KeyboardStoreElement = (string | StoreNonCharEntry);
+export type ComplexKeyboardStore = KeyboardStoreElement[];
+
+export type KeyboardStore = PlainKeyboardStore | ComplexKeyboardStore;
+
+export type VariableStore = { [name: string]: string };
+
+export interface VariableStoreSerializer {
+ loadStore(keyboardID: string, storeName: string): VariableStore;
+ saveStore(keyboardID: string, storeName: string, storeMap: VariableStore): void;
+}
/**
* Defines common behaviors associated with system stores.
@@ -61,9 +87,9 @@ export class MutableSystemStore extends SystemStore {
* Handles checks against the current platform.
*/
export class PlatformSystemStore extends SystemStore {
- private readonly kbdInterface: KeyboardInterface;
+ private readonly kbdInterface: KeyboardHarness;
- constructor(keyboardInterface: KeyboardInterface) {
+ constructor(keyboardInterface: KeyboardHarness) {
super(SystemStoreIDs.TSS_PLATFORM);
this.kbdInterface = keyboardInterface;
@@ -131,4 +157,4 @@ export class PlatformSystemStore extends SystemStore {
// Everything we checked against was valid and had matches - it's a match!
return true;
}
-}
\ No newline at end of file
+}
diff --git a/web/src/engine/js-processor/tsconfig.json b/web/src/engine/js-processor/tsconfig.json
new file mode 100644
index 0000000000..a57467139b
--- /dev/null
+++ b/web/src/engine/js-processor/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ // While the actual references themselves are headless, it compiles against the DOM-reliant OSK module.
+ "extends": "../../tsconfig.dom.json",
+
+ "compilerOptions": {
+ "baseUrl": "./",
+ "outDir": "../../../build/engine/js-processor/obj/",
+ "tsBuildInfoFile": "../../../build/engine/js-processor/obj/tsconfig.tsbuildinfo",
+ "rootDir": "./src"
+ },
+
+ "include": [ "**/*.ts" ],
+}
diff --git a/web/src/engine/main/build.sh b/web/src/engine/main/build.sh
index cceb9b4b8b..4e6ca67db1 100755
--- a/web/src/engine/main/build.sh
+++ b/web/src/engine/main/build.sh
@@ -18,6 +18,7 @@ builder_describe "Builds the Keyman Engine for Web's common top-level base class
"@/common/predictive-text" \
"@/web/src/engine/interfaces build" \
"@/web/src/engine/device-detect build" \
+ "@/web/src/engine/js-processor build" \
"@/web/src/engine/package-cache build" \
"@/web/src/engine/osk build" \
"@/developer/src/kmc-model test" \
diff --git a/web/src/engine/main/src/contextManagerBase.ts b/web/src/engine/main/src/contextManagerBase.ts
index c3f9581003..e745dbe312 100644
--- a/web/src/engine/main/src/contextManagerBase.ts
+++ b/web/src/engine/main/src/contextManagerBase.ts
@@ -1,5 +1,6 @@
import { EventEmitter } from 'eventemitter3';
-import { ManagedPromise, type Keyboard, type KeyboardInterface, type OutputTarget } from '@keymanapp/keyboard-processor';
+import { ManagedPromise, type Keyboard, type OutputTarget } from '@keymanapp/keyboard-processor';
+import { type KeyboardInterface } from 'keyman/engine/js-processor';
import { StubAndKeyboardCache, type KeyboardStub } from 'keyman/engine/package-cache';
import { PredictionContext } from 'keyman/engine/interfaces';
import { EngineConfiguration } from './engineConfiguration.js';
diff --git a/web/src/engine/main/src/engineConfiguration.ts b/web/src/engine/main/src/engineConfiguration.ts
index c66d3bd805..bb82844c56 100644
--- a/web/src/engine/main/src/engineConfiguration.ts
+++ b/web/src/engine/main/src/engineConfiguration.ts
@@ -1,6 +1,7 @@
import { EventEmitter } from "eventemitter3";
-import { DeviceSpec, KeyboardProperties, ManagedPromise, OutputTarget, physicalKeyDeviceAlias, RuleBehavior, SpacebarText } from "@keymanapp/keyboard-processor";
+import { DeviceSpec, KeyboardProperties, ManagedPromise, OutputTarget, physicalKeyDeviceAlias, SpacebarText } from "@keymanapp/keyboard-processor";
+import { RuleBehavior } from 'keyman/engine/js-processor';
import { PathConfiguration, PathOptionDefaults, PathOptionSpec } from "keyman/engine/interfaces";
import { Device } from "keyman/engine/device-detect";
import { KeyboardStub } from "keyman/engine/package-cache";
diff --git a/web/src/engine/main/src/hardKeyboard.ts b/web/src/engine/main/src/hardKeyboard.ts
index a07904f4a6..491073f729 100644
--- a/web/src/engine/main/src/hardKeyboard.ts
+++ b/web/src/engine/main/src/hardKeyboard.ts
@@ -1,6 +1,7 @@
import { EventEmitter } from "eventemitter3";
-import { Keyboard, KeyMapping, KeyEvent, type RuleBehavior, Codes } from "@keymanapp/keyboard-processor";
-import { KeyEventSourceInterface } from 'keyman/engine/events';
+import { Keyboard, KeyMapping, KeyEvent, Codes } from "@keymanapp/keyboard-processor";
+import { type RuleBehavior } from 'keyman/engine/js-processor';
+import { KeyEventSourceInterface } from 'keyman/engine/osk';
import { ModifierKeyConstants } from '@keymanapp/common-types';
interface EventMap {
diff --git a/web/src/engine/main/src/headless/inputProcessor.ts b/web/src/engine/main/src/headless/inputProcessor.ts
index 7b89a0e242..99a31db609 100644
--- a/web/src/engine/main/src/headless/inputProcessor.ts
+++ b/web/src/engine/main/src/headless/inputProcessor.ts
@@ -12,15 +12,12 @@ import {
Codes,
isEmptyTransform,
type Keyboard,
- KeyboardInterface,
- KeyboardProcessor,
type KeyEvent,
Mock,
type OutputTarget,
- type ProcessorInitOptions,
- RuleBehavior,
- SystemStoreIDs,
} from "@keymanapp/keyboard-processor";
+import { KeyboardInterface, KeyboardProcessor, RuleBehavior, type ProcessorInitOptions, SystemStoreIDs } from 'keyman/engine/js-processor';
+
import { TranscriptionCache } from "./transcriptionCache.js";
export class InputProcessor {
diff --git a/web/src/engine/main/src/keyboardInterface.ts b/web/src/engine/main/src/keyboardInterface.ts
index a18bafecd0..d966c26bad 100644
--- a/web/src/engine/main/src/keyboardInterface.ts
+++ b/web/src/engine/main/src/keyboardInterface.ts
@@ -1,6 +1,5 @@
-import {
- KeyboardInterface as KeyboardInterfaceBase, KeyboardObject,
-} from "@keymanapp/keyboard-processor";
+import { KeyboardObject } from "@keymanapp/keyboard-processor";
+import { KeyboardInterface as KeyboardInterfaceBase } from 'keyman/engine/js-processor';
import { KeyboardStub, RawKeyboardStub, toUnprefixedKeyboardId as unprefixed } from 'keyman/engine/package-cache';
import { ContextManagerBase } from './contextManagerBase.js';
diff --git a/web/src/engine/main/src/keymanEngine.ts b/web/src/engine/main/src/keymanEngine.ts
index eaa54e5994..86ff9d5898 100644
--- a/web/src/engine/main/src/keymanEngine.ts
+++ b/web/src/engine/main/src/keymanEngine.ts
@@ -1,4 +1,5 @@
-import { type Keyboard, KeyboardKeymanGlobal, ProcessorInitOptions } from "@keymanapp/keyboard-processor";
+import { type KeyEvent, type Keyboard, KeyboardKeymanGlobal } from "@keymanapp/keyboard-processor";
+import { ProcessorInitOptions, RuleBehavior } from 'keyman/engine/js-processor';
import { DOMKeyboardLoader as KeyboardLoader } from "@keymanapp/keyboard-processor/dom-keyboard-loader";
import { InputProcessor } from './headless/inputProcessor.js';
import { OSKView } from "keyman/engine/osk";
@@ -10,7 +11,7 @@ import KeyboardInterface from "./keyboardInterface.js";
import { ContextManagerBase } from "./contextManagerBase.js";
import HardKeyboardBase from "./hardKeyboard.js";
import { LegacyAPIEvents } from "./legacyAPIEvents.js";
-import { KeyEventHandler, EventNames, EventListener, LegacyEventEmitter } from "keyman/engine/events";
+import { EventNames, EventListener, LegacyEventEmitter } from "keyman/engine/events";
import DOMCloudRequester from "keyman/engine/package-cache/dom-requester";
import KEYMAN_VERSION from "@keymanapp/keyman-version";
@@ -29,6 +30,9 @@ function determineBaseLayout(): string {
}
}
+export type KeyEventFullResultCallback = (result: RuleBehavior, error?: Error) => void;
+export type KeyEventFullHandler = (event: KeyEvent, callback?: KeyEventFullResultCallback) => void;
+
export default class KeymanEngine<
Configuration extends EngineConfiguration,
ContextManager extends ContextManagerBase,
@@ -47,7 +51,7 @@ export default class KeymanEngine<
protected keyEventRefocus?: () => void;
- private keyEventListener: KeyEventHandler = (event, callback) => {
+ private keyEventListener: KeyEventFullHandler = (event, callback) => {
const outputTarget = this.contextManager.activeTarget;
if(!this.contextManager.activeKeyboard || !outputTarget) {
diff --git a/web/src/engine/main/src/variableStoreCookieSerializer.ts b/web/src/engine/main/src/variableStoreCookieSerializer.ts
index 35b51150c0..62c250329a 100644
--- a/web/src/engine/main/src/variableStoreCookieSerializer.ts
+++ b/web/src/engine/main/src/variableStoreCookieSerializer.ts
@@ -1,4 +1,4 @@
-import { VariableStore, VariableStoreSerializer } from "@keymanapp/keyboard-processor";
+import { VariableStore, VariableStoreSerializer } from 'keyman/engine/js-processor';
import { CookieSerializer } from "keyman/engine/dom-utils";
// While there's little reason we couldn't store all of a keyboard's store values within
diff --git a/web/src/engine/main/tsconfig.json b/web/src/engine/main/tsconfig.json
index 9711d06a77..e3b2b0616c 100644
--- a/web/src/engine/main/tsconfig.json
+++ b/web/src/engine/main/tsconfig.json
@@ -15,5 +15,6 @@
{ "path": "../osk" },
{ "path": "../package-cache" },
{ "path": "../interfaces" },
+ { "path": "../js-processor" }
]
}
diff --git a/web/src/engine/osk/src/index.ts b/web/src/engine/osk/src/index.ts
index 388ea32750..f2a543e175 100644
--- a/web/src/engine/osk/src/index.ts
+++ b/web/src/engine/osk/src/index.ts
@@ -4,6 +4,7 @@ export { default as OSKView } from './views/oskView.js';
export { default as FloatingOSKView, FloatingOSKViewConfiguration } from './views/floatingOskView.js';
export { default as AnchoredOSKView } from './views/anchoredOskView.js';
export { default as InlinedOSKView } from './views/inlinedOskView.js';
+export { type KeyEventResultCallback, type KeyEventHandler, KeyEventSourceInterface } from './views/keyEventSource.interface.js';
export { BannerController } from './banner/bannerController.js';
// Is referenced by at least one desktop UI module.
export { FloatingOSKCookie as FloatingOSKViewCookie } from './views/floatingOskCookie.js';
diff --git a/web/src/engine/events/src/keyEventSource.interface.ts b/web/src/engine/osk/src/views/keyEventSource.interface.ts
similarity index 78%
rename from web/src/engine/events/src/keyEventSource.interface.ts
rename to web/src/engine/osk/src/views/keyEventSource.interface.ts
index d3c39fa49d..36a065bd32 100644
--- a/web/src/engine/events/src/keyEventSource.interface.ts
+++ b/web/src/engine/osk/src/views/keyEventSource.interface.ts
@@ -1,5 +1,6 @@
import { EventEmitter } from "eventemitter3";
-import { type KeyEvent, type RuleBehavior } from "@keymanapp/keyboard-processor";
+import { type KeyEvent } from "@keymanapp/keyboard-processor";
+import { type RuleBehavior } from 'keyman/engine/js-processor';
export type KeyEventResultCallback = (result: RuleBehavior, error?: Error) => void;
export type KeyEventHandler = (event: KeyEvent, callback?: KeyEventResultCallback) => void;
diff --git a/web/src/engine/osk/src/views/oskView.ts b/web/src/engine/osk/src/views/oskView.ts
index d55eb8a8f8..2a400a8662 100644
--- a/web/src/engine/osk/src/views/oskView.ts
+++ b/web/src/engine/osk/src/views/oskView.ts
@@ -16,16 +16,16 @@ import {
Keyboard,
KeyboardProperties,
ManagedPromise,
- type MinimalCodesInterface,
- type MutableSystemStore,
- type SystemStoreMutationHandler
+ type MinimalCodesInterface
} from '@keymanapp/keyboard-processor';
import { createUnselectableElement, getAbsoluteX, getAbsoluteY, StylesheetManager } from 'keyman/engine/dom-utils';
-import { EventListener, KeyEventHandler, KeyEventSourceInterface, LegacyEventEmitter } from 'keyman/engine/events';
+import { EventListener, LegacyEventEmitter } from 'keyman/engine/events';
+import { type MutableSystemStore, type SystemStoreMutationHandler } from 'keyman/engine/js-processor';
import Configuration from '../config/viewConfiguration.js';
import Activator, { StaticActivator } from './activator.js';
import TouchEventPromiseMap from './touchEventPromiseMap.js';
+import { KeyEventHandler, KeyEventSourceInterface } from './keyEventSource.interface.js';
import { DEFAULT_GESTURE_PARAMS, GestureParams } from '../input/gestures/specsForLayout.js';
// These will likely be eliminated from THIS file at some point.\
diff --git a/web/src/engine/osk/src/visualKeyboard.ts b/web/src/engine/osk/src/visualKeyboard.ts
index a8152a0db0..d082663454 100644
--- a/web/src/engine/osk/src/visualKeyboard.ts
+++ b/web/src/engine/osk/src/visualKeyboard.ts
@@ -31,7 +31,7 @@ import {
import { createStyleSheet, StylesheetManager } from 'keyman/engine/dom-utils';
-import { KeyEventHandler, KeyEventResultCallback } from 'keyman/engine/events';
+import { KeyEventHandler, KeyEventResultCallback } from './views/keyEventSource.interface.js';
import GlobeHint from './globehint.interface.js';
import KeyboardView from './components/keyboardView.interface.js';
diff --git a/common/web/keyboard-processor/tests/dom/cases/domKeyboardLoader.spec.ts b/web/src/test/auto/dom/cases/keyboard-processor/domKeyboardLoader.spec.ts
similarity index 95%
rename from common/web/keyboard-processor/tests/dom/cases/domKeyboardLoader.spec.ts
rename to web/src/test/auto/dom/cases/keyboard-processor/domKeyboardLoader.spec.ts
index 1965adc853..63414662fa 100644
--- a/common/web/keyboard-processor/tests/dom/cases/domKeyboardLoader.spec.ts
+++ b/web/src/test/auto/dom/cases/keyboard-processor/domKeyboardLoader.spec.ts
@@ -1,7 +1,8 @@
import { assert } from 'chai';
import { DOMKeyboardLoader } from '@keymanapp/keyboard-processor/dom-keyboard-loader';
-import { extendString, KeyboardHarness, Keyboard, KeyboardInterface, MinimalKeymanGlobal, Mock, DeviceSpec, KeyboardKeymanGlobal } from '@keymanapp/keyboard-processor';
+import { extendString, KeyboardHarness, Keyboard, MinimalKeymanGlobal, Mock, DeviceSpec, KeyboardKeymanGlobal } from '@keymanapp/keyboard-processor';
+import { KeyboardInterface } from 'keyman/engine/js-processor';
declare let window: typeof globalThis;
// KeymanEngine from the web/ folder... when available.
diff --git a/web/src/test/auto/dom/kbdLoader.ts b/web/src/test/auto/dom/kbdLoader.ts
index 629ade205e..2254011857 100644
--- a/web/src/test/auto/dom/kbdLoader.ts
+++ b/web/src/test/auto/dom/kbdLoader.ts
@@ -4,11 +4,11 @@ import {
import {
Keyboard,
- KeyboardInterface,
KeyboardProperties,
MinimalKeymanGlobal
} from '@keymanapp/keyboard-processor';
+import { KeyboardInterface } from 'keyman/engine/js-processor';
import { KeyboardStub } from 'keyman/engine/package-cache';
const loader = new DOMKeyboardLoader(new KeyboardInterface(window, MinimalKeymanGlobal));
diff --git a/web/src/test/auto/headless/engine/interfaces/prediction/predictionContext.spec.js b/web/src/test/auto/headless/engine/interfaces/prediction/predictionContext.spec.js
index 6bd0f7555c..3738f6824e 100644
--- a/web/src/test/auto/headless/engine/interfaces/prediction/predictionContext.spec.js
+++ b/web/src/test/auto/headless/engine/interfaces/prediction/predictionContext.spec.js
@@ -4,7 +4,8 @@ import sinon from 'sinon';
import { LanguageProcessor, TranscriptionCache } from 'keyman/engine/main';
import { PredictionContext } from 'keyman/engine/interfaces';
import { Worker as LMWorker } from "@keymanapp/lexical-model-layer/node";
-import { DeviceSpec, KeyboardProcessor, Mock } from '@keymanapp/keyboard-processor';
+import { DeviceSpec, Mock } from '@keymanapp/keyboard-processor';
+import { KeyboardProcessor } from 'keyman/engine/js-processor';
function compileDummyModel(suggestionSets) {
return `
diff --git a/web/src/tools/testing/recorder-core/src/nodeProctor.ts b/web/src/tools/testing/recorder-core/src/nodeProctor.ts
index 6f6d7fd6a0..852002d4b3 100644
--- a/web/src/tools/testing/recorder-core/src/nodeProctor.ts
+++ b/web/src/tools/testing/recorder-core/src/nodeProctor.ts
@@ -8,8 +8,9 @@ import {
RecordedSyntheticKeystroke
} from "./index.js";
-import { KeyboardInterface, KeyEvent, KeyEventSpec, KeyboardProcessor, Mock, type OutputTarget, KeyboardHarness } from "@keymanapp/keyboard-processor";
+import { KeyEvent, KeyEventSpec, Mock, type OutputTarget, KeyboardHarness } from "@keymanapp/keyboard-processor";
import { DeviceSpec } from "@keymanapp/web-utils";
+import { KeyboardInterface, KeyboardProcessor } from 'keyman/engine/js-processor';
export default class NodeProctor extends Proctor {
private keyboardWithHarness: KeyboardHarness;
diff --git a/web/src/tools/testing/recorder-core/tsconfig.json b/web/src/tools/testing/recorder-core/tsconfig.json
index a7bd08c374..38af26e1a4 100644
--- a/web/src/tools/testing/recorder-core/tsconfig.json
+++ b/web/src/tools/testing/recorder-core/tsconfig.json
@@ -17,6 +17,7 @@
{ "path": "../../../../../common/web/keyman-version" },
{ "path": "../../../../../common/web/utils/" },
{ "path": "../../../../../common/web/keyboard-processor/" },
- { "path": "../../../../../common/web/lm-message-types" }
+ { "path": "../../../../../common/web/lm-message-types" },
+ { "path": "../../../engine/js-processor" }
],
}