👁 v4 Plugin Migration Guide

Upgrading to Plugins v4 Developer Notes

Improvements:

  • Over 10x faster plugin builder!
  • Plugin builder handles more plugin structural edge-cases

Notes:

  1. New plugin builder (lipsurf-cli build) by default does not check types run with lipsurf-cli build --check for type checking.

  2. Add a apiVersion: 2 property to the root of your plugin. apiVersion 1 (the default) is for plugins in LipSurf < 4.0.0.

  3. New command properties:
    onlyFinal?: true - an alternative to previous uses of delay. Only execute the command if it’s the final guess we get from the STT.
    priority?: number - allow non-dynamic commands to take priority over dynamic commands. Dynamic commands have a default priority of 10000. Lower numbers take higher priority.

  4. transcript: string parameter on pageFn, fn, match::fn, and niceFn changed to TsData which is {preTs: string, normTs: string}. normTs is the same old transcript: string and preTs is before transcript preprocessing, which includes lowercasing, removing certain punctuation, trimming spaces etc.

  5. Argument for wildcard (match strings with “*”) are now TsData with users custom shortcuts applied (in pageFn, fn, match::fn and niceFn)

  6. (temporary) It seems enums are not working, use constants for now instead as a workaround.

I’m trying to update my plug ins but ran into this error: Cannot find name 'TsData'. the full log is here

I ran into this with my own plug in but it’s also what happens when I check out this commit and run yarn build with no other changes

Probably something simple I’m missing?

It’s defined here: types/plugin-interface.d.ts at master · LipSurf/types · GitHub

Looks like you didn’t upgrade to the new types. Something like this should work:
yarn upgrade lipsurf-types --latest
yarn add --dev https://github.com/lipsurf/cli

That seemed to help, after I cloned github.com/lipsurf/cli. Without the extra clone I was getting error Package "lipsurf-cli" refers to a non-existing file '"/mnt/c/Users/aki/code/cli"'. from yarn add --dev... Just including it for completeness in case it should be added to a readme…

Now I’m getting another error from yarn build

$ yarn build
yarn run v1.22.5
$ lipsurf-cli build
/bin/sh: 1: lipsurf-cli: Permission denied
error Command failed with exit code 127.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

This is after yarn upgrade and yarn add. Some stackoverflow post suggested this, but got another error

$ npm rebuild
...
npm ERR! code ENOENT
npm ERR! syscall chmod
npm ERR! path /mnt/c/Users/aki/code/LipSurf-plugins/node_modules/lipsurf-cli/lib/lipsurf-cli.js
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, chmod '/mnt/c/Users/aki/code/LipSurf-plugins/node_modules/lipsurf-cli/lib/lipsurf-cli.js'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent

Not sure what it is about lipsurf-cli that causes these problems. I’m on Windows with WSL fwiw

1 Like

you can change the line in package.json that has lipsurf-cli to this:

"lipsurf-cli": "https://github.com/lipsurf/cli",

and then run yarn and yarn build again. FYI I’m correcting this line right now and pushing to the plugin repo.

Best not to mix using npm and yarn.

That seemed to have done something, it’s able to find lipsurf-cli now but getting errors from that:

aki@SECTOID:/mnt/c/Users/aki/code/LipSurf-plugins$ yarn build
yarn run v1.22.5
$ lipsurf-cli build
/mnt/c/Users/aki/code/LipSurf-plugins/node_modules/.bin/lipsurf-cli: 2: use strict: Permission denied
/mnt/c/Users/aki/code/LipSurf-plugins/node_modules/.bin/lipsurf-cli: 3: //#: not found
internal/modules/cjs/loader.js:883
  throw err;
  ^

Error: Cannot find module 'lipsurf-common/dev.cjs'
Require stack:
- /mnt/c/Users/aki/code/LipSurf-plugins/node_modules/lipsurf-cli/lib/lipsurf-cli.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
    at Function.Module._load (internal/modules/cjs/loader.js:725:27)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (/mnt/c/Users/aki/code/LipSurf-plugins/node_modules/lipsurf-cli/lib/lipsurf-cli.js:14:19)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/mnt/c/Users/aki/code/LipSurf-plugins/node_modules/lipsurf-cli/lib/lipsurf-cli.js'
  ]
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

fwiw I tried on an old macbook and have the same issue, so seems unrelated to Windows

I see the problem. Sorry about this, and thanks for your patience! Fixing it now.

ok, now it’s fixed. Can you get a new version of lipsurf-cli by running:

yarn add --dev https://github.com/lipsurf/cli
yarn add --dev typescript

you might need to do a yarn cache clean and rm -r node_modules beforehand if that doesn’t work.

Thanks, I think this worked. I did run into a few things which I figure I’ll report:

I had to remove use of enum and I don’t understand why… I was able to work around it but I’m curious:

Error building Kitsun: Error: Error evaluating TypeError: Cannot read property 'Flipping' of undefined

I also still get this error but seems to be minor without any impact:

/mnt/c/Users/aki/code/LipSurf-plugins/node_modules/.bin/lipsurf-cli: 2: use strict: Permission denied
/mnt/c/Users/aki/code/LipSurf-plugins/node_modules/.bin/lipsurf-cli: 3: //#: not found

When I do yarn build Kitsun I get this error, along with what looks like dumped compiled TS:

Error: Error evaluating TypeError: PluginBase.util.getLanguage is not a function

There’s no .ls file in dist.

But if I do yarn build --check Kitsun I don’t get any errors and the ls file is built, it appears to be working after I loaded it into Lipsurf and tested it.

Also, is yarn build:prod the way to go to distribute the files? I recall it used to strip out console.log, but seems not to now?

I now remember I had to do the same in one of my plugins. It’s a side effect of the way we evaluate plugins. I will put fixing this on the todo list. Thanks for reporting!

It’s a workaround for getting --experimental-vm-modules working in a node script. It’s expected and harmless.

This is because you have called PluginBase.util.getLanguage top-level which is undefined behavior. You should move that to init instead (I see 3 other initializations you should additionally move). Basically nothing should be called or initialized top-level. Declaring is fine though.

Top-level is evaluated when the plugin is built - so asking what language is set doesn’t make sense at that time. On the other hand, init is evaluated on the page when LipSurf is turned on and if the plugin is activated and match's the page. destroy is it’s counterpart.

It’s funny that --check did not catch the same error. I will look into it!

Yes. At a minimum it should strip whitespace. Not stripping logs by default is a regression, I will fix that.

Ok is there an easy way to debug this? I don’t remember running into it before. The output of the error is just the entire minified source of the plugin so hard to pin down the issue. I moved things to init but am hitting this:

Error building Kitsun: Error: Error evaluating TypeError: (intermediate value)(intermediate value)(...) is not a function

edit:
I thought it was the prefectures data which was at the top level but still getting the same on this commit

There is a bug upstream in the SWC library we use that caused this. I’ve made a temporary workaround.

If you get the latest version of lipsurf-cli (yarn add --dev https://github.com/lipsurf/cli) it should build (builds for me).

constants are actually fine to have top-level, btw.

This works for me, thanks for your help

1 Like

Is it possible that this broke something? When I was trying to update one of the other plugins today I did this again: yarn upgrade lipsurf-types --latest but it seemed to break the build. here’s the full log. I had to pin to an older version of lipsurf-types for it to work

I’m also running into an issue with the auto dictate feature, with one of the plugins (Bunpro) Based on the browser logs it appears that the auto dictate is kicking in, and the plugin’s match function is not called. After some testing, I noticed the Bunpro plugin will work up until the first time I focus the input text field. After that, even if I click away, the auto dictate code is taking priority (I see the focus and blur logs which I think are from LS, and I see the blur in this case, but auto dictate still triggers) Since the input field is focused when a flash card is flipped, it breaks the plugin unless I disable Text Input entirely.

Is there a way for a plugin to be configured to disable the new auto dictate feature while the plugin is active? Interestingly this is only an issue with Bunpro, not with Kitsun or Kaniwani. So maybe it’s something about that site that is interfering with the auto dictate feature

Here’s the code and the .ls file if you want to try reproducing

1 Like

Let’s start with this issue. Looks like an old version of webdriverio is still lingering. You can verify with yarn why webdriverio if it’s v6 of webdriver, that’s why you have the issue. If you are using yarn local links, that might be why. I don’t think it handles updated dependencies for linked packages. I would just blow away your node_modules and then run:

yarn
yarn add --dev https://github.com/lipsurf/types
yarn add --dev https://github.com/lipsurf/cli

that will update your yarn lock file to make sure you have the latest commits from those two repos. You can verify with yarn why webdriverio and it should be v7. If not, can you show me the output of yarn why webdriverio?

Thanks that worked along with yarn add --dev typescript. I had thought I already tried deleting node modules, along with yarn cache clean, but I think I had failed to run yarn install before doing build.

1 Like

I see the issue here:

In my testing, the href can have additional parameters (e.g. https://www.bunpro.jp/learn?finished_onboarding=true&grammar_points=[1]) , so I would loosen up this regex.

As long as the context is being entered, it should take priority over auto-dictation.

const BUNPRO_HREF_REGX = /^https?:\/\/(www\.)?bunpro\.jp\/(learn|study|cram)/;

This worked for me.

P.S. to debug context you can do this:

  1. Select a LipSurf Extension javascript context in the console:

image

  1. Paste something like this
    setInterval(() => { console.log(window.PluginBase.util.getContext()) }, 2000)

P.P.S. We want to make the dev mode more powerful, and the dev experience smoother. Based on your comments here, the first thing we’d like to do is make building plugins simpler. It will be as simple as creating a .ts file in a folder, then running yarn init, and yarn add lipsurf-cli then yarn build. We would also like to make reloading the plugin in the extension automatic, based on when the file was last modified (so you don’t need to go into the options and re-upload) Do you have any other suggestions or feedback on the development experience?

Good catch, but in my testing the href didn’t have any params and I still had the issue

I’m not sure I understand exactly, are you saying that so long as that setInterval is outputting ["Bunpro"] the auto dictate should be off? The Bunpro context is definitely entered, the code is working up until the first click away from the input field, even with the better regex. Here’s how I am able to reproduce the issue now:

  1. Go to https://www.bunpro.jp/study
  2. Say the answer (or だめ) and then つぎ as many times as you like.
  3. I can get through multiple cards this way, and advance through them correctly (Bunpro plugin working)
  4. The input field retains focus between cards, but as soon as I click away once (and blur is logged) the auto dictate “takes over”
  5. Clicking on the field or away doesn’t seem to matter after this point, the auto dictate always has priority

That is the behavior I’m seeing with this code:

Not sure if I’m explaining it correctly or misunderstanding how the LS plugin “context” works

If it can be as easy as this that would be great, it’s certainly the biggest pain point, speaking as someone who is obviously not familiar with the ecosystem.

This would also be useful, I’ve gotten in the habit of adding extra junk into my version string so I could double check that I was actually running the code I expected after reuploading it

The only other suggestion that comes to mind might be to somehow package the boilerplate from this solution so that every plug-in doesn’t have to reimplement it

1 Like