blob: c050a1dd6a015ac26ae06d31b368731b15522b57 [file] [view]
# Josh: Interact with Fuchsia through JavaScript.
This directory is for development of Josh, a Fuchsia JavaScript shell and interpreter.
A less generic name, and more content, is pending.
The current shell is based on JavaScript.
Currently, invoking FIDL calls (and wrappers around FIDL calls) requires
the use of `Promise`s. You can invoke FIDL calls on protocols available from
`/svc` easily by saying something like:
```
svc.fuchsia_kernel_DebugBroker.SendDebugCommand("threadstats")
```
This returns a `Promise`. Followup actions can be taken in the `Promise`'s then
clause. You can also use `async`/`await`, although this is not supported for
direct invocation from the command line.
Arbitrary FIDL requests (those that do not depend on `/svc`) can be sent
using the `fidl.Request` and `fidl.ProtocolClient` API. For example, if you have a
channel to a directory called dirChannel, and you want to open a path within that
directory, you can say:
```
let dirClient = new fidl.ProtocolClient(dirChannel, fidling.fuchsia_io.Directory);
const request = new fidl.Request(fidling.fuchsia_io.Node);
pathClient = request.getProtocolClient();
let openedPromise = pathClient.OnOpen((args) => {
return args;
});
dirClient.Open(
fidling.fuchsia_io.OPEN_RIGHT_READABLE | fidling.fuchsia_io.OPEN_FLAG_DESCRIBE, 0,
path, request.getChannelForServer());
let args = await openedPromise;
// Manipulate args.s or args.info.
fidl.ProtocolClient.close(request.getProtocolClient());
```
Note that available FIDL libraries are available off of a global object called
`fidling`. If a FIDL library you want is not available, please contact the OWNERS
of this directory.
If you want to try the shell, add the package "//src/developer/shell:josh" to
the packages available, shell into the device, and type "josh".
# Create A JavaScript Running Environment
The following is an example of creating a **JavaScript environment** in the Fuchsia
component `factory_josh` which allows JavaScript to run inside. This component contains:
- A list of FIDL IRs (`fidl_json`) to be supported.
- Startup modules (`js_startup_libs`) for the factory environment.
- Standard Josh (`//src/developer/shell/josh:bin`)
The component can be run by others to execute the test scripts sent in, so the component
does not include any application script.
import("//src/developer/shell/generate_fidl_json.gni")
# Select FIDL IRs to be supported (use distribution_fidl_json from generate_fidl_json.gni)
distribution_fidl_json("fidl_json") {
fidl_deps = [
"//sdk/fidl/fuchsia.buildinfo",
"//sdk/fidl/fuchsia.device.manager",
"//sdk/fidl/fuchsia.hardware.backlight",
"//sdk/fidl/fuchsia.hardware.cpu.ctrl",
"//sdk/fidl/fuchsia.hardware.gpio",
"//sdk/fidl/fuchsia.hardware.i2c",
"//sdk/fidl/fuchsia.hardware.light",
"//sdk/fidl/fuchsia.hardware.spi",
"//sdk/fidl/fuchsia.io",
"//sdk/fidl/fuchsia.sysinfo",
]
}
# Include environment startup modules
resource("js_startup_libs") {
sources = [
"startup/hw.js",
"startup/startup.json",
]
outputs = [ "data/lib/startup/{{source_file_part}}" ]
}
fuchsia_component("factory_josh") {
manifest = "meta/factory_josh.cml" # Component manifest for capability routing
deps = [
":fidl_json", # Supported FIDL IRs
":js_startup_libs", # Startup modules
"//src/developer/shell/josh:bin", # Include standard Josh
]
}
When exploring the created component (environment), running `josh` will land on the
Javascript console:
$ ffx component explore <COMPONENT URL/moniker/instance ID> -l namespace
$ josh
QuickJS - Type "\h" for help
qjs > console.log("Hello World!");
Hello World!
# Notes on object representation
FIDL objects are mostly represented with a relatively straightforward conversion to
JSON. This section contains some notes on the details of representation.
## Bits
Bits are represented as `BigInt` values, so that they are not accidentally
affected by JavaScript's lack of integer support.