feat(web): cleanup of variable stores

This addresses code review comments in #15437 and removes some
unnecessary definitions related to variable stores. It keeps the
`VariableStoreSerializer` interface although currently
`VariableStoreCookieSerializer` is the only implementation. Conceptually
IMO it makes sense to use a more abstract interface so that in the future
for example we could easily use a different store for a node
implementation.

Details of this change:
- remove `VariableStoreDictionary` interface and replace with
  `VariableStore` type
- remove `VarStoreSerializer` class and replace with
  ` CookieSerializer<VariableStore>`

Follow-up-of: #15437
Test-bot: skip
This commit is contained in:
Eberhard Beilharz 2026-01-19 15:46:31 +01:00
parent 8d3a6da260
commit 01bee770f9
No known key found for this signature in database
GPG key ID: E9140597606020D3
6 changed files with 19 additions and 44 deletions

View file

@ -22,7 +22,6 @@ import {
type KeyEvent,
type TextStore,
VariableStore,
VariableStoreDictionary,
VariableStoreSerializer,
} from "keyman/engine/keyboard";
import { PlatformSystemStore } from './platformSystemStore.js';
@ -1103,7 +1102,7 @@ export class JSKeyboardInterface extends KeyboardHarness {
* @param stores A dictionary of stores which should be found in the
* keyboard
*/
applyVariableStores(stores: VariableStoreDictionary): void {
applyVariableStores(stores: VariableStore): void {
this.activeKeyboard.variableStores = stores;
}

View file

@ -30,7 +30,7 @@ export { EmulationKeystrokes, LogMessages, DefaultRules } from "./defaultRules.j
export { type KeyDistribution, KeyEventSpec, KeyEvent } from "./keyEvent.js";
export { KeyMapping } from "./keyMapping.js";
export { type SystemStoreMutationHandler, MutableSystemStore, SystemStore, SystemStoreIDs, type SystemStoreDictionary } from "./systemStore.js";
export { type VariableStore, VariableStoreSerializer, VariableStoreDictionary } from "./variableStore.js";
export { type VariableStore, VariableStoreSerializer } from "./variableStore.js";
export { DOMKeyboardLoader } from './keyboards/loaders/domKeyboardLoader.js';
export { SyntheticTextStore } from "./syntheticTextStore.js";

View file

@ -4,7 +4,7 @@ import { ActiveKey, ActiveLayout, ActiveSubKey } from "./activeLayout.js";
import { KeyEvent } from "../keyEvent.js";
import { type TextStore } from "../textStore.js";
import { KeymanWebKeyboard, ModifierKeyConstants, TouchLayout } from "@keymanapp/common-types";
import { VariableStoreDictionary } from "../variableStore.js";
import { VariableStore } from "../variableStore.js";
import ComplexKeyboardStore = KeymanWebKeyboard.ComplexKeyboardStore;
import KeyboardObject = KeymanWebKeyboard.KeyboardObject;
@ -120,9 +120,9 @@ export class JSKeyboard {
*
* @returns an object with each property referencing a variable store
*/
get variableStores(): VariableStoreDictionary {
get variableStores(): VariableStore {
const storeNames = this.scriptObject['KVS'];
let values: VariableStoreDictionary = {};
let values: VariableStore = {};
if(Array.isArray(storeNames)) {
for(let store of storeNames) {
values[store] = this.scriptObject[store];
@ -139,7 +139,7 @@ export class JSKeyboard {
*
* @param values name-value pairs for each store value
*/
set variableStores(values: VariableStoreDictionary) {
set variableStores(values: VariableStore) {
const storeNames = this.scriptObject['KVS'];
if(Array.isArray(storeNames)) {
for(let store of storeNames) {

View file

@ -3,7 +3,7 @@
*/
import { LexicalModelTypes } from '@keymanapp/common-types';
import { Transcription } from './transcription.js';
import { VariableStore, VariableStoreDictionary } from '../variableStore.js';
import { VariableStore } from '../variableStore.js';
import { SystemStoreDictionary } from '../systemStore.js';
/**
@ -34,7 +34,7 @@ export class ProcessorAction {
/**
* A set of variable stores with possible changes to be applied during finalization.
*/
variableStores: VariableStoreDictionary = {};
variableStores: VariableStore = {};
/**
* Denotes a non-output default behavior; this should be evaluated later, against the true keystroke.

View file

@ -4,10 +4,6 @@
* Definitions for variable stores (see kmn reference)
*/
export interface VariableStoreDictionary {
[name: string]: string;
};
export type VariableStore = { [name: string]: string; };
export interface VariableStoreSerializer {

View file

@ -8,42 +8,20 @@ import { CookieSerializer } from "keyman/engine/dom-utils";
// Also of note: there's nothing we can do to allow TS to provide type-checking of
// dynamic property names; they'd have to be known at compile time to facilitate
// strict type checking.
class VarStoreSerializer extends CookieSerializer<VariableStore> {
public constructor(keyboardID: string, storeName: string) {
super(`KeymanWeb_${keyboardID}_Option_${storeName}`);
}
public load(): VariableStore {
return super.load(decodeURIComponent);
}
public save(storeMap: VariableStore) {
super.save(storeMap, encodeURIComponent);
}
/**
* Find all variable stores associated with a given keyboard.
*
* @param {string} keyboardID The keyboard ID whose variable stores are to be found.
*
* @returns An array of VariableStore objects found for the keyboard.
*/
public static findStores(keyboardID: string): VariableStore[] {
const pattern = new RegExp(`^KeymanWeb_${keyboardID}_Option_`);
const matching = CookieSerializer.loadAllMatching<VariableStore>(pattern, decodeURIComponent);
return matching.map(m => m.value);
}
}
export class VariableStoreCookieSerializer implements VariableStoreSerializer {
private getStoreCookieName(keyboardID: string, storeName: string): string {
return `KeymanWeb_${keyboardID}_Option_${storeName}`;
}
public loadStore(keyboardID: string, storeName: string): VariableStore {
const storeCookieSerializer = new VarStoreSerializer(keyboardID, storeName);
return storeCookieSerializer.load();
const storeCookieSerializer = new CookieSerializer<VariableStore>(this.getStoreCookieName(keyboardID, storeName));
return storeCookieSerializer.load(decodeURIComponent);
}
public saveStore(keyboardID: string, storeName: string, storeMap: VariableStore) {
const storeCookieSerializer = new VarStoreSerializer(keyboardID, storeName);
storeCookieSerializer.save(storeMap);
const storeCookieSerializer = new CookieSerializer<VariableStore>(this.getStoreCookieName(keyboardID, storeName));
storeCookieSerializer.save(storeMap, encodeURIComponent);
}
/**
@ -54,6 +32,8 @@ export class VariableStoreCookieSerializer implements VariableStoreSerializer {
* @returns An array of VariableStore objects found for the keyboard.
*/
public findStores(keyboardID: string): VariableStore[] {
return VarStoreSerializer.findStores(keyboardID);
const pattern = new RegExp(`^${this.getStoreCookieName(keyboardID, '')}`);
const matching = CookieSerializer.loadAllMatching<VariableStore>(pattern, decodeURIComponent);
return matching.map(m => m.value);
}
}