Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(web): allows registering precached keyboards #9304

Merged
merged 4 commits into from
Jul 21, 2023

Conversation

jahorton
Copy link
Contributor

Fixes keymanapp/keymanweb.com#77.

The modularized design for KMW's cloud interactions assumes that there's always a Promise for any incoming keyman.register calls. That said, keymanweb.com likes to pre-cache the keyboards query and directly register it in a manner that bypasses cloud queries and the associated Promises. Since there was no Promise bound to the register, KMW had no infrastructure for forwarding the precached stubs.

So, this PR adds in a relatively simple rigging to remedy that issue.

@keymanapp-test-bot skip

@jahorton jahorton added this to the A17S17 milestone Jul 19, 2023
@jahorton jahorton requested a review from mcdurdin as a code owner July 19, 2023 07:26
Copy link
Member

@mcdurdin mcdurdin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM I think

this.cache.addStub(entry);
});
}
} finally { }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this empty finally{} needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are naked try { } statements permitted in JS?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch

The try...catch statement is comprised of a try block and either a catch block, a finally block, or both.

I want to let errors pass through.

  • keyman.register itself is an undocumented API function.
  • Since there's no lead-in Promise, type-checking all possible input variants is... less than straightforward. We can at least be confident for the keymanweb.com use case, though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a naked try{} supposed to do though? It doesn't do anything, does it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😆 time to go home!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this was probably end-of-day brain. It does signal that we acknowledge the potential for errors, but I guess a comment can do that too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed via code-suggestion in the (resolved) comment-chain below.

Comment on lines 101 to 111
// Handles keymanweb.com's precached keyboard array. There is no associated promise,
// so there's nothing handling the `register` call's results otherwise.
this.cloudQueryEngine.on('unboundregister', (registration) => {
// Internal, undocumented use-case of `keyman.register`: precached keyboard loading
// Other uses may trigger errors, especially if there's a type-structure mismatch.
// Those errors should not be handled here; let them surface.
if(Array.isArray(registration)) {
registration.forEach((entry) => {
this.cache.addStub(entry);
});
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given keyman.register was completely undocumented (which is really not a good thing given it definitely is an internal API), it's a bit of a stretch to say this was an undocumented use-case: all use-cases were undocumented.

It's perhaps something you did not consider when you changed the implementation to use promises. This issue underlines just how critical it is to avoid changing APIs, even internal undocumented ones, without full audit of all uses.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. It does help to know such uses exist, though - took a bit to connect the dots once I realized keymanweb.com's caching might be related to the reported issue, especially since nothing else related was broken.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the audit bit -- no one is going to remember everything, so code search is our friend here. For web, it's particularly troublesome given the websites can also interact. And 'register' is an unhelpfully common term so a search for this would have been particularly painful!

But in any case, searching api.keyman.com, keymanweb.com, help.keyman.com, and keyman.com sources any time any 'public' interface is touched on KeymanWeb will probably help with this in future. (All those sites use KeymanWeb or interact with KeymanWeb in some way or other, e.g. bookmarklet, embedded documentation OSK, etc.)

@mcdurdin
Copy link
Member

mcdurdin commented Jul 21, 2023

Test (Keyman - Web) — TeamCity build failed

waaah 😭


08:15:27   file:///var/lib/TeamCity/agent/work/99b311828f4ee7c/keyman/web/build/engine/package-cache/obj/cloud/queryEngine.js:2
08:15:27   import { EventEmitter } from 'eventemitter3';
08:15:27            ^^^^^^^^^^^^
08:15:27   SyntaxError: Named export 'EventEmitter' not found. The requested module 'eventemitter3' is a CommonJS module, which may not support all module.exports as named exports.
08:15:27   CommonJS modules can always be imported via the default export, for example using:
08:15:27   
08:15:27   import pkg from 'eventemitter3';
08:15:27   const { EventEmitter } = pkg;
08:15:27   
08:15:27       at ModuleJob._instantiate (node:internal/modules/esm/module_job:124:21)
08:15:27       at async ModuleJob.run (node:internal/modules/esm/module_job:190:5)

@jahorton jahorton merged commit 59a208d into master Jul 21, 2023
15 checks passed
@jahorton jahorton deleted the fix/web/precached-kbd-registration branch July 21, 2023 06:43
@keyman-server
Copy link
Collaborator

Changes in this pull request will be available for download in Keyman version 17.0.145-alpha

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

bug: Languages dropdown menu is missing in KeymanWeb 17.0.142 build
3 participants