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

JS: Backport³ and more additions & fixes #3961

Open
wants to merge 34 commits into
base: dev
Choose a base branch
from

Merge branch 'dev' into js-backport3-and-more

f8852e4
Select commit
Loading
Failed to load commit list.
Open

JS: Backport³ and more additions & fixes #3961

Merge branch 'dev' into js-backport3-and-more
f8852e4
Select commit
Loading
Failed to load commit list.
Task list completed / task-list-completed Started 2024-10-21 17:51:55 ago

0 / 3 tasks completed

3 tasks still to be completed

Details

Required Tasks

Task Status
backport (here) of backported missing things (there) of great backport & rework (over yonder) xD Incomplete
i separated into individual commits that make sense on their own, might be easier to look there instead of whole diff Incomplete
original authors/contributors credited with co-author where relevant Incomplete
numpad keys support Incomplete
keyboard layout support Incomplete
altPrint() and altPrintln() support Incomplete
quit() function to unlock usb profile (original intent was to alternate badusb profile and mass storage profile, we have this in momentum and other cfw as usbdisk module, but outside scope of this pr, can backport this module later on if you're interested) Incomplete
readAny() to avoid starving read loops with many small reads or hinder usability with few large reads Incomplete
end() to release serial handle allowing new initialization in same script, maybe for gpio usage or different serial port or settings Incomplete
expansion service is automatically disabled to avoid conflict Incomplete
added simple example script we had previously, ported to new remade storage module Incomplete
fixed null ptr crash when user did not pass max len prop. logic of props is from what i can see, always configure view for minimum usable state, props should configure things on top as optional Incomplete
defaultText and defaultTextClear props Incomplete
byte_input Incomplete
there is no file picker based on View object, so this is only gui/* module that is not based on view_factory Incomplete
instead it uses usual dialogs app file picker in sync manner Incomplete
viewDispatcher.currentView to allow users to have extra logic in navigation callbacks for example Incomplete
updated gui example script with showcase of all additions above Incomplete
toString() works correctly on negative numbers, toString(-42) used to give "0" Incomplete
parseInt() Incomplete
toUpperCase() and toLowerCase() Incomplete
example for string functions Incomplete
__filepath and __dirpath to allow relative path contextualization, for example for load() or storage.open() Incomplete
example interactive.js repl script, allows running js in limited capacity without editing files Incomplete
many additions to typedefs that were missing or incomplete, still not everything is documented i believe but getting closer Incomplete
toString(), toUpperCase(), toLowerCase() could all be moved to respective classes i think, for strings there is getprop_builtin_string() in mjs source, can add there, for number there is no such function but may be possible to add another if branch in getprop_builtin() for number type Incomplete
load() accepts a custom scope parameter. with custom scope, assignment in child script is confined to custom scope, lookup is recursive to parent scopes. with no custom scope, code is executed in current scope, so everything is shared like code was inlined Incomplete
for custom scope, we can get custom scope object passed by user and inject __filepath and __dirpath into it, easy Incomplete
for no custom scope, i dont see any good solution: one way is saving current __dirpath and __filepath values from scope, changing them, running load(), then resetting to previous values. might work fine in most cases but if child script runs load() of its own and uses callbacks or things like this, child2 might run a function defined in child1 and then its screwed up. this is a rare edge case of course, if no function callback is passed from child1 to child2 then no code from child1 could run while child2, and second instance of mjs_load() would restore child1's __dirpath and __filepath correctly Incomplete
unit tests Incomplete
example scripts Incomplete
PR has description of feature/bug or link to Confluence/Jira task Incomplete
Description contains actions to verify feature/bugfix Incomplete
I've built this code, uploaded it to the device and verified feature/bugfix Incomplete
We want to maintain a base JS API that is consistent across all firmware flavors. Incomplete
We want JS app developers to be able to leverage additional functionality found in custom firmware editions. Incomplete
We want users not to think about cross-FW compatibility of the scripts that they find online too much. Incomplete
A JS app that works on OFW should also work on a CFW. Incomplete
A JS app that works on a CFW and leverages its extended features may or may not work on OFW. Incomplete
A JS app that does not leverage any additional CFW functionality is guaranteed to work across all firmware editions. Incomplete
A JS app that requires additional CFW functionality will not work on OFW. Incomplete
One can write JS apps that can make use of but do not require additional CFW functionality. Incomplete
CFWs are free to introduce additional JS APIs. Incomplete
CFWs are discouraged from breaking the base JS API found in OFW. Incomplete
CFWs are encouraged to backport any of their extended features into OFW, assuming they are compatible with OFW's vision. Incomplete
checkSdkCompatibility(expectedMajor, expectedMinor): checks if the JS API version is compatible with the one that the script expects (i.e. expectedMajor == actualMajor && expectedMinor >= actualMinor), and if it doesn't, warns the user and asks whether they want to continue executing the script anyways. This is the simplest of the three checks, and it will be automatically inserted in the beginning of the output file unless the developer explicitly asks our JS "toolchain" (SDK) not to do so. By asserting compatibility by default, we guarantee that the user receives a clear warning if their firmware is incompatible with the script instead of cryptic error messages like calling non-callable. Incomplete
isSdkCompatible(expectedMajor, expectedMinor): performs the same check, but just returns the result as a boolean. Incomplete
sdkCompatibilityStatus(expectedMajor, expectedMinor): performs the same check, but returns a more detailed description ("compatible", "firmwareTooOld", "firmwareTooNew") Incomplete
checkSdkVendor(expectedVendor): checks if the JS API vendor matches the one that the script expects, and if it doesn't, warns the user and asks whether they want to continue executing the script anyways. This is the simplest of the two checks for cases where an app requires a feature found in a CFW. This check will not be automatically inserted by our SDK (unlike checkSdkCompatibility). Incomplete
sdkVendor: a string containing the SDK vendor (e.g. "flipperdevices" or "momentum"). A JS app that is able to work without additional features on a best-effort basis may query this global constant to find out whether it can use those features. Incomplete
Both OFW and Momentum are at JS SDK version 1.0. Incomplete
Momentum introduces a feature called "text-input-regex" and bumps its JS SDK version to 1.1. Incomplete
The feature is backported into OFW, bumping its JS SDK version to 1.1 as well. Incomplete
Both OFW and Momentum continue to report true for doesSdkSupport("text-input-regex") until their JS SDK versions are bumped up to 2.0 Incomplete
Starting with JS SDK 2.0, doesSdkSupport("text-input-regex") starts reporting false and checkSdkFeatures(["text-input-regex"]) starts warning the user that a feature is unsupported. I assert that the negative effect from these incorrect results is alleviated thanks to SDK version checks, which will fail if the script expects v1.x but is actually running on 2.x. Incomplete
API versioning in JS got different nature, not like api versioning in API symbols, it should be much easier to maintain it Incomplete
We'll have checkSdk() but as an optional canary Incomplete
If you call it we'll check version and ask user what to do if version doesn't match Incomplete
If your script doesn't contain it, then no checks is done and you'll crash later Incomplete
I'd like to see all of us cooperating on JS API: keep it consistent across all forks, simplifying portability between different firmware flavors. It make sense to expose additional API to query which firmware flavor we are running at Incomplete