This ArcOS wiki is still under active development, and contains errors and unfinished pages.

The basics

The CLI generates two Javascript files for your project: main.js and process.js. The former is the entrypoint of your application: it's the first Javascript file executed by ArcOS when your app is opened. This also happens to be the file that actually spawns your process: the bottom of this file calls runApp, passing in your process, the $METADATA global, and the Shell PID:

const runApp: (process: typeof ThirdPartyAppProcess, metadataPath: string, parentPid?: number, ...args: any[]) => Promise<ThirdPartyAppProcess | undefined>;

The $METADATA global is the path to the .tpa file in your project's src directory. ArcOS reads this file, and uses the entrypoint denoted in it to start the JS code execution.

The process class

process.js does a couple things. First of all it loads the body.html file, which contains the base HTML for your app. Naturally you can also use document.createElement and various other HTML APIs to create elements, but the HTML file is there, and anything in this file be put directly in the body.

The class consists of a couple things by default:

  • the constructor: this is just a basic initializer for the class. if you expect any process-level arguments to come from the spawner of your app, like the path to a file to read or a note to open, replace ...args with the actual variables you expect as arguments, for example:

Out with the old:
-	constructor(handler, pid, parentPid, app, workingDirectory, ...args) {
In with the new:
+	constructor(handler, pid, parentPid, app, workingDirectory, path) {

Let's observe the render method:

async render() {
  const body = this.getBody();
  body.innerHTML = html;
  
  /* Do some interesting stuff here */
  this.myAmazingFunction();
}

First of all, it gets the body of the window using AppProcess.getBody. Then, it sets the innerHTML of that body to the html variable defined at the top of the file. You can use body.querySelector and other DOM operations on this body variable, because it's just a good ol' HTML element.

myAmazingFunction is just a placeholder method I added to show you how classes work. If your experience with JS isn't so great, don't be sad, you can always learn. Here's a good guide I found on the basics of JS classes: https://www.w3schools.com/js/js_classes.asp (w3schools never disappoints).

In-phase process methods

There are several built-in methods in the process class that are executed in different phases of your process. Here's an exhaustive list of them.

  • async start: this method is called when the process is spawned, before the render method. If this method returns false, ArcOS will stop the spawn.

  • async render: called by the app renderer: this method renders your app.

  • async onClose: is expected to return something boolean-ish: determines if the process can be stopped. Return false to prevent the process from stopping (doesn't apply if the kill is forced)

  • async stop: this method is called when the process is killed.

Built-in process methods

These methods are available for you to call in your app process. They range from closing your app to handling multiple instances. Here they are:

closeWindow(kill?: boolean): Promise<void>;

This method is asynchronous: it has to be awaited.

Call this function to close your app. The kill boolean is only relevant for ArcOS' internal process handling; you can safely omit it.


getSingleton(): AppProcess[];

This function returns other instances of your app. This is useful if you want to interact with the methods of one of those other instances.


closeIfSecondInstance(): Promise<AppProcess | undefined>;

This method is asynchronous: it has to be awaited.

If you only want your app to have one instance, call this method conditionally at the very top of your start method, like this:

async start() {
  if (await this.closeIfSecondInstance()) return false;
  // . . .
}

Limitations

When developing an app for ArcOS, it's actively discouraged to access the DOM outside the body of your app. In fact, your app won't be validated for publishing to the (future) app store if it does anything with the html, head or body elements.

ArcOS takes measures to override or modify these globals to prevent direct access to the top-level DOM:

document.body, document.documentElement, document.html, body, window, globalThis

Last updated