tutorial
GETTING STARTED WITH OPENV
Introduction
Welcome to the openv tutorial! This guide will show you how to develop software for the openv operating environment. By the end of this tutorial, you'll have a basic understanding of how to run openv and develop a cross-platform javascript application using openv APIs.
Step 1: Importing openv
To get a real understanding of how openv works, we will start off by manually booting openv in a Node.js environment. First, create a new directory for your project and navigate into it:
mkdir my-openv-app
cd my-openv-app
To avoid setting up a full project, we will simply download the openv bundle and import it locally. (openv is not yet published to npm) Download the latest openv bundle by running the following command:
curl -o openv.bundle.js https://get.openv.party/release/latest/openv.bundle.js
Now, create a new file called index.js
and open it in your favorite text editor.
Add the following code to import and run openv:
import { OpEnv, MemoryRegistry } from './openv.bundle.js';
const openv = new OpEnv(new MemoryRegistry());
console.log("openv is running!"):
Although it seems like nothing happened, we now have the bare minimum to run openv! In the next step, we will add some APIs to our openv environment to make it more useful.
Step 2: Adding APIs
We can install APIs into our openv environment using the installAPI
method.
The simplest API (which is also required for many other APIs) is the IPC api. This API transmits messages over the registry itself
by using the registry's watch
and write
methods. Install the IPC API bundle like we did before
with the openv bundle:
curl -o ipc.bundle.js https://get.openv.party/repo/party/openv/ipc/latest/bundle.js
Now, we can install the IPC API into our openv environment by adding the following code to index.js
:
import { IPCApi } from './ipc.bundle.js';
await openv.installAPI(new IPCApi());
The IPC API is now installed! We can now try a basic example of sending a message to ourselves using the IPC API:
// Note that with typescript, getAPI takes a generic
// parameter for the API type (e.g. getAPI<IPCApi>)
const ipc = openv.getAPI('party.openv.ipc');
ipc.listen("greet", (message) => {
console.log("Listener 1 Received message:", message);
});
ipc.listen("greet", (message) => {
console.log("Listener 2 Received message:", message);
});
let i = 0;
setInterval(() => {
ipc.send("greet", "Hello from openv! Count: " + i++);
}, 1000);
Run the code using Node.js by executing node index.js
in your terminal.
You should see "Listener 1 Received message: Hello from openv! Count: X" and "Listener 2 Received message: Hello from openv! Count: X" printed to the console every second.
Of course, this is very simple and not very useful. The true power of openv comes when we get to the processes API, which allows us to run code in isolated environments,
as well as automatic API importing.
Step 3: Running Code in an Isolated Environment
The processes API allows us to run code in isolated environments, and is how developers will typically create applications for openv. As we are essentially building our system from the ground up, we will need to install quite a few APIs to get the processes API working. Fortunately, the openv-dev.bundle.js bundle contains all the APIs we need to get started preinstalled. Download the latest openv-dev bundle and remove the old bundles by running the following commands:
rm openv.bundle.js ipc.bundle.js
curl -o openv-dev.bundle.js https://get.openv.party/release/latest/openv-dev.bundle.js
Now, update our imports in index.js
to use the new bundle:
import {
OpEnv, MemoryRegistry, IPCApi, ServiceApi,
IdentityApi, ServerApi, ProcessesApi, FsApi, initFs
} from './openv-dev.bundle.js';
And install the new APIs:
await os.installAPI(new OS.ServiceApi());
await os.installAPI(new OS.IdentityApi());
await os.installAPI(new OS.ServerApi());
await os.installAPI(new OS.ProcessesApi());
await os.installAPI(new OS.FsApi());
// Since the FS api is very complex, the dev bundle also includes a function
// to setup a basic in-memory filesystem for us
await initFs(os);
Now we can remove the interval code and the second IPC listener, but leave one listener installed for this example.
Although the processes API is installed now, this api does not work until we register an environment to run processes in.
We need to obtain the process API instance and run the start
method to initialize the API and the
join
method to register ourself as an executor:
const processes = openv.getAPI('party.openv.processes');
await processes.start();
// We will use the id 0 for this executor
await processes.join(0);
Now we can need to write a file to the filesystem that we can run as a process.
Create a new file called script.js
and add the following code:
async function main(args) {
const ipc = openv.getAPI('party.openv.ipc');
ipc.send("greet", "Hello from the process! Args: " + args.join(", "));
}
This code simply sends a message to the IPC API when run. Now, we need to write this file to the filesystem in our index.js
file:
import { promises as nodeFs } from 'fs';
const fs = openv.getAPI('party.openv.fs');
await fs.writeFile('/script.js', new Blob([await nodeFs.readFile('./script.js')]));
Finally, we can run this script as a process using the processes API:
// Run the script with some arguments
await processes.execute(["/script.js", "arg1", "arg2"]);
Now, run the code using Node.js by executing node index.js
in your terminal.
You should see "Listener 1 Received message: Hello from the process! Args: arg1, arg2" printed once when the process is executed.
Congratulations! You have successfully set up a basic openv environment and run code in an isolated environment using the processes API. From here, you can explore more APIs and build more complex applications using openv.