mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-12 20:05:34 +00:00
Implement loading models from specific files.
This commit is contained in:
parent
47580c6af9
commit
f7bd16dade
5 changed files with 47 additions and 11 deletions
|
|
@ -338,10 +338,12 @@ TODO
|
|||
|
||||
- [x] Change `context` to `contexts`.
|
||||
- [x] Change `contexts` to `context`....
|
||||
- [] Figure out what a `Context` will be
|
||||
- [x] Figure out what a `Context` will be
|
||||
- [x] Implement hack to make `global` inherit from `self`
|
||||
- [x] Define on `self.registerModel(factory: (c) => Model)` protocol
|
||||
- [x] Describe `contexts`
|
||||
- [x] Implement loading a model from a file.
|
||||
- [ ] Document `suggestions`
|
||||
- [ ] make simple `index.html` that demos a dummy model
|
||||
- [ ] make an `error` initialization message.
|
||||
- [ ] TypeScript!
|
||||
|
|
|
|||
4
index.js
4
index.js
|
|
@ -21,7 +21,7 @@ class LMLayer {
|
|||
/**
|
||||
* [async] Waits for the model's initialization.
|
||||
*/
|
||||
initialize(_acceptConfiguration) {
|
||||
initialize({model, configuration }) {
|
||||
if (this._configuration) {
|
||||
return Promise.resolve(this._configuration);
|
||||
}
|
||||
|
|
@ -30,9 +30,11 @@ class LMLayer {
|
|||
// _onMessage() will resolve this Promise.
|
||||
return new Promise((resolve, _reject) => {
|
||||
this._cast('initialize', {
|
||||
model,
|
||||
configuration: {
|
||||
maxLeftContextCodeUnits: 32,
|
||||
supportsRightContexts: false,
|
||||
...configuration
|
||||
}
|
||||
});
|
||||
this._resolveInitialized = resolve;
|
||||
|
|
|
|||
13
lmlayer.js
13
lmlayer.js
|
|
@ -52,7 +52,7 @@ function onMessageWhenUninitialized(event) {
|
|||
}
|
||||
|
||||
// Import the model.
|
||||
let model = loadModel(configuration.path, configuration);
|
||||
let model = loadModel(event.data.model, configuration);
|
||||
transitionToReadyState(model);
|
||||
|
||||
// Ready! Send desired configuration.
|
||||
|
|
@ -69,7 +69,7 @@ function transitionToReadyState(model) {
|
|||
* Responds to `predict` messages with a `suggestions` message.
|
||||
*/
|
||||
onMessage = function onMessageWhenReady(event) {
|
||||
const {message, token} = event.data;
|
||||
const {message, token, transform, context} = event.data;
|
||||
|
||||
if (message !== 'predict') {
|
||||
throw new Error('invalid message');
|
||||
|
|
@ -82,10 +82,9 @@ function transitionToReadyState(model) {
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO: rip contexts out of message.
|
||||
let rawSuggestions = model.predict();
|
||||
let rawSuggestions = model.predict(context, transform);
|
||||
|
||||
// Sort in-place according to weight.
|
||||
// Sort in-place according to weight, ascending.
|
||||
rawSuggestions.sort((a, b) => a.weight - b.weight);
|
||||
|
||||
// Convert the internal suggestion format to the one required by the keyboard.
|
||||
|
|
@ -114,8 +113,8 @@ function cast(message, parameters) {
|
|||
/**
|
||||
* Loads the model from a separate file.
|
||||
*/
|
||||
function loadModel(_path /* : string */, configuration /* : Configuration */) {
|
||||
importScripts('./models/en-x-test-derek.js');
|
||||
function loadModel(path /* : string */, configuration /* : Configuration */) {
|
||||
importScripts(path);
|
||||
/**
|
||||
* The model MUST call registerModel() which ultimately defines
|
||||
* createModel() to a function.
|
||||
|
|
|
|||
33
models/en-x-test-teapot.js
Normal file
33
models/en-x-test-teapot.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* This is a test model that simply returns "teapot" when given the context of
|
||||
* «I'm a little ».
|
||||
*/
|
||||
registerModel(function () {
|
||||
return {
|
||||
predict(context, transform) {
|
||||
return [
|
||||
{
|
||||
transform: {
|
||||
insert: 'teapot',
|
||||
deleteLeft: transform.insert.length,
|
||||
deleteRight: 0,
|
||||
},
|
||||
displayAs: '🍵',
|
||||
weight: 0.00,
|
||||
}
|
||||
];
|
||||
|
||||
/* TODO:
|
||||
if (context.wordsLeft === ["I'm", "a", "little"] &&
|
||||
transform.insert === 't') {
|
||||
}
|
||||
|
||||
return [];
|
||||
*/
|
||||
},
|
||||
|
||||
configuration: {
|
||||
}
|
||||
};
|
||||
});
|
||||
/*global registerModel*/
|
||||
4
test.js
4
test.js
|
|
@ -11,7 +11,7 @@ test('It provide context to LMLayer', async t => {
|
|||
const lm = new LMLayer;
|
||||
|
||||
// Wait for the language model to initialize and declare its configuration.
|
||||
let configuration = await lm.initialize({ model: 'en-x-derek' });
|
||||
let configuration = await lm.initialize({ model: './models/en-x-test-derek.js' });
|
||||
// The model should as for 32 code units of context to the left of the
|
||||
// cursor.
|
||||
t.is(configuration.leftContextCodeUnits, 32);
|
||||
|
|
@ -46,7 +46,7 @@ test('It should reject when predictions crash', async t => {
|
|||
t.plan(1);
|
||||
|
||||
const lm = new LMLayer;
|
||||
await lm.initialize({ model: 'en-x-derek' });
|
||||
await lm.initialize({ model: './models/en-x-test-derek.js' });
|
||||
|
||||
try {
|
||||
await lm.predict({
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue